Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

Incorrect "expression is not assignable" error for dependent __is_[X_]assignable type trait expressions in function template signatures #34600

Open Quuxplusone opened 6 years ago

Quuxplusone commented 6 years ago
Bugzilla Link PR35627
Status NEW
Importance P normal
Reported by Tom Honermann (thonerma@synopsys.com)
Reported on 2017-12-11 08:38:58 -0800
Last modified on 2017-12-11 14:58:10 -0800
Version 5.0
Hardware All All
CC erich.keane@intel.com, llvm-bugs@lists.llvm.org, sig-rnd-sat-clang-bugs@synopsys.com
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
This issue reproduces for Clang 3.2-5.0 and current Clang 6.0 trunk.

Clang appears to incorrectly parse dependent __is_assignable,
__is_nothrow_assignable, and __is_trivially_assignable type trait helper
expressions that appear within the signature of a function template.  The
following test case fails for each of these traits:

$ cat t.cpp
template<typename T>
decltype(__is_assignable(T,T)) ft();
auto x = &ft<int>;

$ clang --version
clang version 6.0.0 (trunk 312994)
Target: x86_64-unknown-linux-gnu
...

$ clang -c -fms-extensions -std=c++11 t.cpp
t.cpp:2:29: error: expression is not assignable
decltype(__is_assignable(T,T)) ft();
                            ^
1 error generated.
Quuxplusone commented 6 years ago

FWIW, It seems that "is_assignable<int,int>" is supposed to be false? So I think this is actually doing what it is supposed to be doing. See: https://stackoverflow.com/questions/19920213/why-is-stdis-assignable-counter-intuitive Also, see the example here: http://en.cppreference.com/w/cpp/types/is_assignable

Quuxplusone commented 6 years ago
(In reply to Erich Keane from comment #1)
> FWIW, It seems that "is_assignable<int,int>" is supposed to be false?  So I
> think this is actually doing what it is supposed to be doing.

Since the expression appears in an unevaluated context, I would not expect it
to matter if the result were true or false if actually evaluated.  (pedantic:
the test case is exercising the __is_assignable type trait builtin, not
std::is_assignable)

The test case is the result of my testing name mangling support for type trait
helpers.
Quuxplusone commented 6 years ago

Ah, I see. I missed that it was an unevaluated context. It seems (from what I can tell) that we don't have the machinery to prevent greedy evaluation in this case for builtins. We apparently count on the template handling code to take care of it.

Quuxplusone commented 6 years ago
(In reply to Erich Keane from comment #3)
> Ah, I see.  I missed that it was an unevaluated context.  It seems (from
> what I can tell) that we don't have the machinery to prevent greedy
> evaluation in this case for builtins.  We apparently count on the template
> handling code to take care of it.

The only builtins I've encountered problems with are the three noted in comment
0.  All the other builtin type trait helpers I've tested are handled as
expected.  For example, substitute __is_base_of for __is_assignable.

However, Clang currently lacks name mangling support for TypeTraitExpr, so in
that case, you'll get an (appropriate) error.  Our fork of Clang has added
rudimentary support for mangling these expressions.