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