summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaOverload.cpp6
-rw-r--r--clang/test/Sema/enable_if.c21
-rw-r--r--clang/test/SemaCXX/enable_if.cpp23
3 files changed, 49 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 04751d21bfa..ad95a5ca46f 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -5974,8 +5974,12 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl *Function, ArrayRef<Expr *> Args,
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() &&
diff --git a/clang/test/Sema/enable_if.c b/clang/test/Sema/enable_if.c
index 1cc14659021..a11f53eb493 100644
--- a/clang/test/Sema/enable_if.c
+++ b/clang/test/Sema/enable_if.c
@@ -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
diff --git a/clang/test/SemaCXX/enable_if.cpp b/clang/test/SemaCXX/enable_if.cpp
index 7ec07aa8b0c..81308136c48 100644
--- a/clang/test/SemaCXX/enable_if.cpp
+++ b/clang/test/SemaCXX/enable_if.cpp
@@ -417,3 +417,26 @@ template <int N> constexpr int callTemplated() { return templated<N>(); }
constexpr int B = callTemplated<0>(); // expected-error{{initialized by a constant expression}} expected-error@-2{{no matching function for call to 'templated'}} expected-note{{in instantiation of function template}} expected-note@-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}}
+}
+}
OpenPOWER on IntegriCloud