Patchwork [trans-mem] Avoid ICE with transaction expressions vs constant expressions.

login
register
mail settings
Submitter Richard Henderson
Date Nov. 5, 2011, 12:34 a.m.
Message ID <4EB484B2.6010409@redhat.com>
Download mbox | patch
Permalink /patch/123724/
State New
Headers show

Comments

Richard Henderson - Nov. 5, 2011, 12:34 a.m.
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.
Paolo Carlini - Nov. 5, 2011, 12:54 a.m.
Hi,
> 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.
I believe that this:

+    error (keyword == RID_TRANSACTION_RELAXED
+	   ? "%<__transaction_relaxed%>  without transactional memory "
+             "support enabled"
+	   : "%<__transaction_atomic%>  without transactional memory "
+             "support enabled");

isn't translated correctly. Maybe better wrapping the strings in G_().

Paolo.

Patch

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