[llvm-branch-commits] [cfe-branch] r278479 - Merging r278471:

George Burgess IV via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Thu Aug 11 22:11:46 PDT 2016


Author: gbiv
Date: Fri Aug 12 00:11:46 2016
New Revision: 278479

URL: http://llvm.org/viewvc/llvm-project?rev=278479&view=rev
Log:
Merging r278471:
------------------------------------------------------------------------
r278471 | gbiv | 2016-08-11 21:12:31 -0700 (Thu, 11 Aug 2016) | 11 lines

[Sema] Fix a crash on variadic enable_if functions.

Currently, when trying to evaluate an enable_if condition, we try to
evaluate all arguments a user passes to a function. Given that we can't
use variadic arguments from said condition anyway, not converting them
is a reasonable thing to do. So, this patch makes us ignore any varargs
when attempting to check an enable_if condition.

We'd crash because, in order to convert an argument, we need its
ParmVarDecl. Variadic arguments don't have ParmVarDecls.

------------------------------------------------------------------------

Modified:
    cfe/branches/release_39/lib/Sema/SemaOverload.cpp
    cfe/branches/release_39/test/Sema/enable_if.c
    cfe/branches/release_39/test/SemaCXX/enable_if.cpp

Modified: cfe/branches/release_39/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/lib/Sema/SemaOverload.cpp?rev=278479&r1=278478&r2=278479&view=diff
==============================================================================
--- cfe/branches/release_39/lib/Sema/SemaOverload.cpp (original)
+++ cfe/branches/release_39/lib/Sema/SemaOverload.cpp Fri Aug 12 00:11:46 2016
@@ -5975,8 +5975,12 @@ EnableIfAttr *Sema::CheckEnableIf(Functi
   SmallVector<Expr *, 16> ConvertedArgs;
   bool InitializationFailed = false;
 
+  // Ignore any variadic parameters. Converting them is pointless, since the
+  // user can't refer to them in the enable_if condition.
+  unsigned ArgSizeNoVarargs = std::min(Function->param_size(), Args.size());
+
   // Convert the arguments.
-  for (unsigned I = 0, E = Args.size(); I != E; ++I) {
+  for (unsigned I = 0; I != ArgSizeNoVarargs; ++I) {
     ExprResult R;
     if (I == 0 && !MissingImplicitThis && isa<CXXMethodDecl>(Function) &&
         !cast<CXXMethodDecl>(Function)->isStatic() &&

Modified: cfe/branches/release_39/test/Sema/enable_if.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/test/Sema/enable_if.c?rev=278479&r1=278478&r2=278479&view=diff
==============================================================================
--- cfe/branches/release_39/test/Sema/enable_if.c (original)
+++ cfe/branches/release_39/test/Sema/enable_if.c Fri Aug 12 00:11:46 2016
@@ -149,4 +149,25 @@ void PR27122_ext() {
   regular_enable_if(1, 2); // expected-error{{too many arguments}}
   regular_enable_if(); // expected-error{{too few arguments}}
 }
+
+// We had a bug where we'd crash upon trying to evaluate varargs.
+void variadic_enable_if(int a, ...) __attribute__((enable_if(a, ""))); // expected-note 6 {{disabled}}
+void variadic_test() {
+  variadic_enable_if(1);
+  variadic_enable_if(1, 2);
+  variadic_enable_if(1, "c", 3);
+
+  variadic_enable_if(0); // expected-error{{no matching}}
+  variadic_enable_if(0, 2); // expected-error{{no matching}}
+  variadic_enable_if(0, "c", 3); // expected-error{{no matching}}
+
+  int m;
+  variadic_enable_if(1);
+  variadic_enable_if(1, m);
+  variadic_enable_if(1, m, "c");
+
+  variadic_enable_if(0); // expected-error{{no matching}}
+  variadic_enable_if(0, m); // expected-error{{no matching}}
+  variadic_enable_if(0, m, 3); // expected-error{{no matching}}
+}
 #endif

Modified: cfe/branches/release_39/test/SemaCXX/enable_if.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/test/SemaCXX/enable_if.cpp?rev=278479&r1=278478&r2=278479&view=diff
==============================================================================
--- cfe/branches/release_39/test/SemaCXX/enable_if.cpp (original)
+++ cfe/branches/release_39/test/SemaCXX/enable_if.cpp Fri Aug 12 00:11:46 2016
@@ -417,3 +417,26 @@ template <int N> constexpr int callTempl
 constexpr int B = callTemplated<0>(); // expected-error{{initialized by a constant expression}} expected-error at -2{{no matching function for call to 'templated'}} expected-note{{in instantiation of function template}} expected-note at -9{{candidate disabled}}
 static_assert(callTemplated<1>() == 1, "");
 }
+
+namespace variadic {
+void foo(int a, int b = 0, ...) __attribute__((enable_if(a && b, ""))); // expected-note 6{{disabled}}
+
+void testFoo() {
+  foo(1, 1);
+  foo(1, 1, 2);
+  foo(1, 1, 2, 3);
+
+  foo(1, 0); // expected-error{{no matching}}
+  foo(1, 0, 2); // expected-error{{no matching}}
+  foo(1, 0, 2, 3); // expected-error{{no matching}}
+
+  int m;
+  foo(1, 1);
+  foo(1, 1, m);
+  foo(1, 1, m, 3);
+
+  foo(1, 0); // expected-error{{no matching}}
+  foo(1, 0, m); // expected-error{{no matching}}
+  foo(1, 0, m, 3); // expected-error{{no matching}}
+}
+}




More information about the llvm-branch-commits mailing list