]> granicus.if.org Git - clang/commitdiff
Prevent unreachable when checking invalid multiversion decls.
authorErich Keane <erich.keane@intel.com>
Fri, 4 Jan 2019 15:24:06 +0000 (15:24 +0000)
committerErich Keane <erich.keane@intel.com>
Fri, 4 Jan 2019 15:24:06 +0000 (15:24 +0000)
CPUSpecifc/CPUDispatch call resolution assumed that all declarations
that would be passed are valid, however this was an invalid assumption.
This patch deals with those situations by making the valid version take
priority.  Note that the checked ordering is arbitrary, since both are
replaced by calls to the resolver later.

Change-Id: I7ff2ec88c55a721d51bc1f39ea1a1fe242b4e45f

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350398 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaOverload.cpp
test/Sema/attr-cpuspecific.c

index 6f50dd9bccd76b28ad6b7b17e86a4fb011d7ddc2..257eef435fd454a4c965cb3c82350166e4f12939 100644 (file)
@@ -9023,6 +9023,11 @@ static bool isBetterMultiversionCandidate(const OverloadCandidate &Cand1,
       !Cand2.Function->isMultiVersion())
     return false;
 
+  // If Cand1 is invalid, it cannot be a better match, if Cand2 is invalid, this
+  // is obviously better.
+  if (Cand1.Function->isInvalidDecl()) return false;
+  if (Cand2.Function->isInvalidDecl()) return true;
+
   // If this is a cpu_dispatch/cpu_specific multiversion situation, prefer
   // cpu_dispatch, else arbitrarily based on the identifiers.
   bool Cand1CPUDisp = Cand1.Function->hasAttr<CPUDispatchAttr>();
index 4d21a8c894d26876ab4119a036d09905fe3142cd..d15a65ea1fc550ed21bb034ca2beaae37ec10fc2 100644 (file)
@@ -92,3 +92,15 @@ __vectorcall int __attribute__((cpu_specific(sandybridge))) diff_cc(void);
 int __attribute__((cpu_dispatch(atom))) disp_with_body(void) {
   return 5;
 }
+
+// expected-error@+1 {{invalid option 'INVALID'}}
+int __attribute__((cpu_specific(INVALID))) called_invalid_value(void){ return 1;}
+// expected-warning@+3 {{attribute declaration must precede definition}}
+// expected-note@-2 2 {{previous definition is here}}
+// expected-error@+1 {{redefinition of}}
+int __attribute__((cpu_specific(pentium_iii))) called_invalid_value(void){ return 2;}
+int __attribute__((cpu_specific(pentium_4))) called_invalid_value(void){ return 3;}
+
+int use3(void) {
+  return called_invalid_value();
+}