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 "" } */
+}