this ICE on valid happens only with checking enabled - that explains why we didn't notice it so far - but I think points to a minor but substantive correctness issue. In short, we ICE when build_conditional_expr calls save_expr, which in turn calls contain_placeholder_p, which doesn't handle correctly the sizeof(int), and tries to use TREE_CONSTANT on the INTEGER_TYPE. I think that in general we simply have to explicitly handle both kinds of sizeof in contains_placeholder_p: even for a type as simple as INTEGER_TYPE the result may not be trivial, ie, type_contains_placeholder_1 checks the bounds:

    case REAL_TYPE:
      /* Here we just check the bounds.  */

I'm finishing testing the below on x86_64-linux, all good so far.

Thanks, Paolo.


2018-02-12  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/84333
        * tree.c (contains_placeholder_p): Explicitly handle both kinds
        of SIZEOF_EXPR, ie, type and expr operand.

2018-02-12  Paolo Carlini  <paolo.carl...@oracle.com>

        PR c++/84333
        * g++.dg/template/sizeof16.C: New.
Index: testsuite/g++.dg/template/sizeof16.C
--- testsuite/g++.dg/template/sizeof16.C        (nonexistent)
+++ testsuite/g++.dg/template/sizeof16.C        (working copy)
@@ -0,0 +1,6 @@
+// PR c++/84333
+template<typename> int foo()
+  return sizeof(int) > 1 ? : 1;
Index: tree.c
--- tree.c      (revision 257588)
+++ tree.c      (working copy)
@@ -3733,6 +3733,12 @@ contains_placeholder_p (const_tree exp)
             a PLACEHOLDER_EXPR. */
          return 0;
+       case SIZEOF_EXPR:
+         if (TYPE_P (TREE_OPERAND (exp, 0)))
+           return type_contains_placeholder_p (TREE_OPERAND (exp, 0));
+         else
+           return CONTAINS_PLACEHOLDER_P (TREE_OPERAND (exp, 0));

Reply via email to