There we actually two ICEs here -- one with -fgnu-tm that Torvald 
pointed me at, and one without -fgnu-tm that I of course stumbled
upon while fumble-fingering the command-line to test the thing.

Committed to branch.


r~
            * cp/parser.c (enum non_integral_constant): Add NIC_TRANSACTION.
            (cp_parser_non_integral_constant_expression): Handle it.
            (cp_parser_transaction_expression): Generate an error if TM is
            not enabled.  Use cp_parser_non_integral_constant_expression.
            * testsuite/c-c++-common/tm/trxn-expr-2.c: New test.

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index d52a75d..7a7cfe8 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -106,7 +106,9 @@ typedef enum non_integral_constant {
   /* a comma operator */
   NIC_COMMA,
   /* a call to a constructor */
-  NIC_CONSTRUCTOR
+  NIC_CONSTRUCTOR,
+  /* a transaction expression */
+  NIC_TRANSACTION
 } non_integral_constant;
 
 /* The various kinds of errors about name-lookup failing. */
@@ -2682,6 +2684,10 @@ cp_parser_non_integral_constant_expression (cp_parser  
*parser,
                error ("a call to a constructor "
                       "cannot appear in a constant-expression");
                return true;
+             case NIC_TRANSACTION:
+               error ("a transaction expression "
+                      "cannot appear in a constant-expression");
+               return true;
              case NIC_THIS:
                msg = "this";
                break;
@@ -26656,6 +26662,14 @@ cp_parser_transaction_expression (cp_parser *parser, 
enum rid keyword)
 
   gcc_assert (keyword == RID_TRANSACTION_ATOMIC
       || keyword == RID_TRANSACTION_RELAXED);
+
+  if (!flag_tm)
+    error (keyword == RID_TRANSACTION_RELAXED
+          ? "%<__transaction_relaxed%> without transactional memory "
+             "support enabled"
+          : "%<__transaction_atomic%> without transactional memory "
+             "support enabled");
+
   token = cp_parser_require_keyword (parser, keyword,
       (keyword == RID_TRANSACTION_ATOMIC ? RT_TRANSACTION_ATOMIC
           : RT_TRANSACTION_RELAXED));
@@ -26680,7 +26694,10 @@ cp_parser_transaction_expression (cp_parser *parser, 
enum rid keyword)
     }
   parser->in_transaction = old_in;
 
-  return ret;
+  if (cp_parser_non_integral_constant_expression (parser, NIC_TRANSACTION))
+    return error_mark_node;
+
+  return (flag_tm ? ret : error_mark_node);
 }
 
 /* Parse a function-transaction-block.
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index cb92178..e75589e 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -8140,6 +8140,7 @@ potential_constant_expression_1 (tree t, bool want_rval, 
tsubst_flags_t flags)
     case STMT_EXPR:
     case EXPR_STMT:
     case BIND_EXPR:
+    case TRANSACTION_EXPR:
       if (flags & tf_error)
         error ("expression %qE is not a constant-expression", t);
       return false;
diff --git a/gcc/testsuite/c-c++-common/tm/trxn-expr-2.c 
b/gcc/testsuite/c-c++-common/tm/trxn-expr-2.c
new file mode 100644
index 0000000..0ef6526
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tm/trxn-expr-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* Make sure that we don't just crash without -fgnu-tm enabled.  */
+/* { dg-options "" } */
+
+int x;
+
+int foo(void)
+{
+  return __transaction_atomic (x + 1);         /* { dg-error "" } */
+}
+
+int bar(void)
+{
+  return __transaction_relaxed (x + 1);                /* { dg-error "" } */
+}

Reply via email to