Hi!
We instantiate FIX_TRUNC_EXPR using cp_build_unary_op, but that function
doesn't look like a good match for this tree, what it really does for it is:
1) handle error_operand_p
2) on ia64 only diagnose __fpreg uses (I believe a cast of __fpreg to int is
fine, so we shouldn't warn)
3) and then it does:
argtype = TREE_TYPE (arg);
return build1 (code, argtype, arg);
which creates FIX_TRUNC_EXPR with the type of the argument rather than
the integral type it should have.
The following patch thus bypasses that function and just builds the
FIX_TRUNC_EXPR with the right type. I think we don't need to tsubst the
type, because if it is type dependent, we wouldn't be creating
FIX_TRUNC_EXPR, but record it just as a some kind of conversion.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2018-03-19 Jakub Jelinek <[email protected]>
PR c++/84942
* pt.c (tsubst_copy_and_build) <case FIX_TRUNC_EXPR>: Don't call
cp_build_unary_op, just use build1.
* g++.dg/cpp1y/pr84942.C: New test.
--- gcc/cp/pt.c.jj 2018-03-16 21:11:04.440773108 +0100
+++ gcc/cp/pt.c 2018-03-19 10:58:39.803657613 +0100
@@ -17495,8 +17495,10 @@ tsubst_copy_and_build (tree t,
complain|decltype_flag));
case FIX_TRUNC_EXPR:
- RETURN (cp_build_unary_op (FIX_TRUNC_EXPR, RECUR (TREE_OPERAND (t, 0)),
- false, complain));
+ op1 = RECUR (TREE_OPERAND (t, 0));
+ if (error_operand_p (op1))
+ RETURN (error_mark_node);
+ RETURN (build1 (FIX_TRUNC_EXPR, TREE_TYPE (t), op1));
case ADDR_EXPR:
op1 = TREE_OPERAND (t, 0);
--- gcc/testsuite/g++.dg/cpp1y/pr84942.C.jj 2018-03-19 11:04:16.201588211
+0100
+++ gcc/testsuite/g++.dg/cpp1y/pr84942.C 2018-03-19 11:02:37.950609950
+0100
@@ -0,0 +1,7 @@
+// PR c++/84942
+// { dg-do compile { target c++14 } }
+// { dg-options "-w" }
+
+int a(__attribute__((b((int)__builtin_inf() * 1ULL / auto))));
+// { dg-error "expected primary-expression before" "" { target *-*-* } .-1 }
+// { dg-error "declared as implicit template" "" { target *-*-* } .-2 }
Jakub