Gently ping.

> On May 27, 2015, at 10:44 AM, Ettore Speziale <[email protected]> 
> wrote:
> 
> Hello Nick,
> 
> thanks for taking a look at the patch.
> 
>> I think this will cause the enable_if expression to be evaluated multiple 
>> times if the expression is not dependent but appertains to a function 
>> template, such as:
>> 
>>  template <typename T> void foo(int i, T t) __attribute__((enable_if(i==0, 
>> ""))) {}
>> 
>> I'm not sure how to fix that without hoisting it up to ActOnCallExpr? Could 
>> you check whether this is a real problem?
> 
> I tried to run this small example:
> 
> // RUN: clang++ -emit-llvm -S -o - test.cpp
> 
> struct foo {
>  template <typename T>
>  int f(int i, T t) __attribute__((enable_if(i == 0, "only when 'i' is 
> zero")));
> 
>  template <typename T>
>  int g(int i, float j, T t) __attribute__((enable_if(i == 0, "only when 'i' 
> is zero")));
>  template <typename T>
>  int g(int i, double j, T t) __attribute__((enable_if(i == 0, "only when 'i' 
> is zero"))); 
> };
> 
> int bar(foo in, int ti, float tf) {
>  return in.f(1, ti) + in.f(1, tf);
> } 
> 
> int baz(foo in, float fj, double dj, int ti, float tf) {
>  return in.g(1, fj, ti) + in.g(1, fj, tf) + in.g(1, dj, ti) + in.g(1, dj, tf);
> } 
> 
> With a modified version of clang that dump the expression just before it is 
> being computed in CheckEnableIf:
> 
> diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
> index 95af64e..361a4f3 100644
> --- a/lib/Sema/SemaOverload.cpp
> +++ b/lib/Sema/SemaOverload.cpp
> @@ -5887,6 +5887,7 @@ EnableIfAttr *Sema::CheckEnableIf(FunctionDecl 
> *Function, ArrayRef<Expr *> Args,
>       continue;
>     }
> 
> +    llvm::errs() << "EVALUATE EXPR\n"; EIA->getCond()->dump();
>     if (!EIA->getCond()->EvaluateWithSubstitution(
>             Result, Context, Function, llvm::makeArrayRef(ConvertedArgs))) {
>       if (!ContainsValueDependentExpr)
> 
> The bar function exercise the code in my patch, the baz function exercise 
> existing code.
> 
> This is what I get:
> 
> ┌─[ettore@vesta] - [/tmp] - [2015-05-27 10:11:24]
> └─[1] <> clang++ -emit-llvm -S -o - test.cpp
> EVALUATE EXPR
> BinaryOperator 0x7fc06507e2c8 '_Bool' '=='
> |-ImplicitCastExpr 0x7fc06507e2b0 'int' <LValueToRValue>
> | `-DeclRefExpr 0x7fc06507e288 'int' lvalue ParmVar 0x7fc06507df98 'i' 'int'
> `-IntegerLiteral 0x7fc06507be00 'int' 0
> test.cpp:13:13: error: no matching member function for call to 'f'
>  return in.f(1, ti) + in.f(1, tf);
>         ~~~^
> test.cpp:4:7: note: candidate disabled: only when 'i' is zero
>  int f(int i, T t) __attribute__((enable_if(i == 0, "only when 'i' is 
> zero")));
>      ^                                      ~~~~~~
> EVALUATE EXPR
> BinaryOperator 0x7fc06507e780 '_Bool' '=='
> |-ImplicitCastExpr 0x7fc06507e768 'int' <LValueToRValue>
> | `-DeclRefExpr 0x7fc06507e740 'int' lvalue ParmVar 0x7fc06507e480 'i' 'int'
> `-IntegerLiteral 0x7fc06507be00 'int' 0
> test.cpp:13:27: error: no matching member function for call to 'f'
>  return in.f(1, ti) + in.f(1, tf);
>                       ~~~^
> test.cpp:4:7: note: candidate disabled: only when 'i' is zero
>  int f(int i, T t) __attribute__((enable_if(i == 0, "only when 'i' is 
> zero")));
>      ^                                      ~~~~~~
> EVALUATE EXPR
> BinaryOperator 0x7fc06507f188 '_Bool' '=='
> |-ImplicitCastExpr 0x7fc06507f170 'int' <LValueToRValue>
> | `-DeclRefExpr 0x7fc06507f148 'int' lvalue ParmVar 0x7fc06507ee00 'i' 'int'
> `-IntegerLiteral 0x7fc06507c338 'int' 0
> EVALUATE EXPR
> BinaryOperator 0x7fc06507f698 '_Bool' '=='
> |-ImplicitCastExpr 0x7fc06507f680 'int' <LValueToRValue>
> | `-DeclRefExpr 0x7fc06507f658 'int' lvalue ParmVar 0x7fc06507f308 'i' 'int'
> `-IntegerLiteral 0x7fc06507c828 'int' 0
> test.cpp:17:13: error: no matching member function for call to 'g'
>  return in.g(1, fj, ti) + in.g(1, fj, tf) + in.g(1, dj, ti) + in.g(1, dj, tf);
>         ~~~^
> test.cpp:7:7: note: candidate disabled: only when 'i' is zero
>  int g(int i, float j, T t) __attribute__((enable_if(i == 0, "only when 'i' 
> is zero")));
>      ^                                               ~~~~~~
> test.cpp:9:7: note: candidate disabled: only when 'i' is zero
>  int g(int i, double j, T t) __attribute__((enable_if(i == 0, "only when 'i' 
> is zero"))); 
>      ^                                                ~~~~~~
> EVALUATE EXPR
> BinaryOperator 0x7fc06507fc38 '_Bool' '=='
> |-ImplicitCastExpr 0x7fc06507fc20 'int' <LValueToRValue>
> | `-DeclRefExpr 0x7fc06507fbf8 'int' lvalue ParmVar 0x7fc06507f8b0 'i' 'int'
> `-IntegerLiteral 0x7fc06507c338 'int' 0
> EVALUATE EXPR
> BinaryOperator 0x7fc0650804c8 '_Bool' '=='
> |-ImplicitCastExpr 0x7fc0650804b0 'int' <LValueToRValue>
> | `-DeclRefExpr 0x7fc065080488 'int' lvalue ParmVar 0x7fc06507fd30 'i' 'int'
> `-IntegerLiteral 0x7fc06507c828 'int' 0
> test.cpp:17:31: error: no matching member function for call to 'g'
>  return in.g(1, fj, ti) + in.g(1, fj, tf) + in.g(1, dj, ti) + in.g(1, dj, tf);
>                           ~~~^
> test.cpp:7:7: note: candidate disabled: only when 'i' is zero
>  int g(int i, float j, T t) __attribute__((enable_if(i == 0, "only when 'i' 
> is zero")));
>      ^                                               ~~~~~~
> test.cpp:9:7: note: candidate disabled: only when 'i' is zero
>  int g(int i, double j, T t) __attribute__((enable_if(i == 0, "only when 'i' 
> is zero"))); 
>      ^                                                ~~~~~~
> EVALUATE EXPR
> BinaryOperator 0x7fc06507f188 '_Bool' '=='
> |-ImplicitCastExpr 0x7fc06507f170 'int' <LValueToRValue>
> | `-DeclRefExpr 0x7fc06507f148 'int' lvalue ParmVar 0x7fc06507ee00 'i' 'int'
> `-IntegerLiteral 0x7fc06507c338 'int' 0
> EVALUATE EXPR
> BinaryOperator 0x7fc06507f698 '_Bool' '=='
> |-ImplicitCastExpr 0x7fc06507f680 'int' <LValueToRValue>
> | `-DeclRefExpr 0x7fc06507f658 'int' lvalue ParmVar 0x7fc06507f308 'i' 'int'
> `-IntegerLiteral 0x7fc06507c828 'int' 0
> test.cpp:17:49: error: no matching member function for call to 'g'
>  return in.g(1, fj, ti) + in.g(1, fj, tf) + in.g(1, dj, ti) + in.g(1, dj, tf);
>                                             ~~~^
> test.cpp:7:7: note: candidate disabled: only when 'i' is zero
>  int g(int i, float j, T t) __attribute__((enable_if(i == 0, "only when 'i' 
> is zero")));
>      ^                                               ~~~~~~
> test.cpp:9:7: note: candidate disabled: only when 'i' is zero
>  int g(int i, double j, T t) __attribute__((enable_if(i == 0, "only when 'i' 
> is zero"))); 
>      ^                                                ~~~~~~
> EVALUATE EXPR
> BinaryOperator 0x7fc06507fc38 '_Bool' '=='
> |-ImplicitCastExpr 0x7fc06507fc20 'int' <LValueToRValue>
> | `-DeclRefExpr 0x7fc06507fbf8 'int' lvalue ParmVar 0x7fc06507f8b0 'i' 'int'
> `-IntegerLiteral 0x7fc06507c338 'int' 0
> EVALUATE EXPR
> BinaryOperator 0x7fc0650804c8 '_Bool' '=='
> |-ImplicitCastExpr 0x7fc0650804b0 'int' <LValueToRValue>
> | `-DeclRefExpr 0x7fc065080488 'int' lvalue ParmVar 0x7fc06507fd30 'i' 'int'
> `-IntegerLiteral 0x7fc06507c828 'int' 0
> test.cpp:17:67: error: no matching member function for call to 'g'
>  return in.g(1, fj, ti) + in.g(1, fj, tf) + in.g(1, dj, ti) + in.g(1, dj, tf);
>                                                               ~~~^
> test.cpp:7:7: note: candidate disabled: only when 'i' is zero
>  int g(int i, float j, T t) __attribute__((enable_if(i == 0, "only when 'i' 
> is zero")));
>      ^                                               ~~~~~~
> test.cpp:9:7: note: candidate disabled: only when 'i' is zero
>  int g(int i, double j, T t) __attribute__((enable_if(i == 0, "only when 'i' 
> is zero"))); 
>      ^                                                ~~~~~~
> 6 errors generated.
> 
> I can see the expression being evaluated once for each call to f, and twice 
> for each call to g, as it has two overloads. So it seems that my patch and 
> the current implementation works in the same way from this point of view. 
> 
> Did I understand correctly?
> 
> Thanks,
> Ettore Speziale


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to