r278471 - [Sema] Fix a crash on variadic enable_if functions.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Aug 11 22:08:19 PDT 2016


Sure, looks safe enough to me.

On 11 Aug 2016 9:23 p.m., "George Burgess IV" <george.burgess.iv at gmail.com>
wrote:

Hi Richard,

Would you mind if I merged this into the 3.9 branch? :)

Thanks,
George

On Thu, Aug 11, 2016 at 9:12 PM, George Burgess IV via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: gbiv
> Date: Thu Aug 11 23:12:31 2016
> New Revision: 278471
>
> URL: http://llvm.org/viewvc/llvm-project?rev=278471&view=rev
> Log:
> [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/trunk/lib/Sema/SemaOverload.cpp
>     cfe/trunk/test/Sema/enable_if.c
>     cfe/trunk/test/SemaCXX/enable_if.cpp
>
> Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaO
> verload.cpp?rev=278471&r1=278470&r2=278471&view=diff
> ============================================================
> ==================
> --- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaOverload.cpp Thu Aug 11 23:12:31 2016
> @@ -5974,8 +5974,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/trunk/test/Sema/enable_if.c
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/enab
> le_if.c?rev=278471&r1=278470&r2=278471&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/Sema/enable_if.c (original)
> +++ cfe/trunk/test/Sema/enable_if.c Thu Aug 11 23:12:31 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/trunk/test/SemaCXX/enable_if.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/
> enable_if.cpp?rev=278471&r1=278470&r2=278471&view=diff
> ============================================================
> ==================
> --- cfe/trunk/test/SemaCXX/enable_if.cpp (original)
> +++ cfe/trunk/test/SemaCXX/enable_if.cpp Thu Aug 11 23:12:31 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}}
> +}
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160811/bc40490c/attachment-0001.html>


More information about the cfe-commits mailing list