summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/testsuite/c-c++-common/tm/volatile-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/tm/pr46654.c4
-rw-r--r--gcc/trans-mem.c30
4 files changed, 36 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index fceb2c0e90a..d251f1d7958 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2015-10-02 Jason Merrill <jason@redhat.com>
+
+ PR c/59218
+ * trans-mem.c (volatile_lvalue_p): Rename from volatile_var_p.
+ (diagnose_tm_1_op): Also diagnose volatile accesses in
+ transaction_safe function.
+
2015-10-02 Jonathan Wakely <jwakely@redhat.com>
* system.h (malloc.h): Don't include obsolete header.
diff --git a/gcc/testsuite/c-c++-common/tm/volatile-1.c b/gcc/testsuite/c-c++-common/tm/volatile-1.c
new file mode 100644
index 00000000000..eb3799dd972
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tm/volatile-1.c
@@ -0,0 +1,10 @@
+// Transaction-unsafe testcase from TM TS.
+// { dg-options -fgnu-tm }
+
+volatile int * p = 0;
+__attribute ((transaction_safe))
+int f() {
+ int x = 0; // ok: not volatile
+ p = &x; // ok: the pointer is not volatile
+ int i = *p; // { dg-error "volatile" "read through volatile glvalue" }
+}
diff --git a/gcc/testsuite/gcc.dg/tm/pr46654.c b/gcc/testsuite/gcc.dg/tm/pr46654.c
index bb63b685844..563474eaf68 100644
--- a/gcc/testsuite/gcc.dg/tm/pr46654.c
+++ b/gcc/testsuite/gcc.dg/tm/pr46654.c
@@ -7,7 +7,7 @@ int y;
void foo(volatile int x)
{
__transaction_atomic {
- x = 5; /* { dg-error "invalid volatile use of 'x' inside transaction" } */
+ x = 5; /* { dg-error "invalid use of volatile lvalue inside transaction" } */
x += y;
y++;
}
@@ -20,7 +20,7 @@ volatile int i = 0;
void george()
{
__transaction_atomic {
- if (i == 2) /* { dg-error "invalid volatile use of 'i' inside transaction" } */
+ if (i == 2) /* { dg-error "invalid use of volatile lvalue inside transaction" } */
i = 1;
}
}
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 5b43d86f6da..488c20e4c64 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -594,32 +594,36 @@ struct diagnose_tm
gimple *stmt;
};
-/* Return true if T is a volatile variable of some kind. */
+/* Return true if T is a volatile lvalue of some kind. */
static bool
-volatile_var_p (tree t)
+volatile_lvalue_p (tree t)
{
- return (SSA_VAR_P (t)
+ return ((SSA_VAR_P (t) || REFERENCE_CLASS_P (t))
&& TREE_THIS_VOLATILE (TREE_TYPE (t)));
}
/* Tree callback function for diagnose_tm pass. */
static tree
-diagnose_tm_1_op (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
- void *data)
+diagnose_tm_1_op (tree *tp, int *walk_subtrees, void *data)
{
struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
struct diagnose_tm *d = (struct diagnose_tm *) wi->info;
- if (volatile_var_p (*tp)
- && d->block_flags & DIAG_TM_SAFE
- && !d->saw_volatile)
+ if (TYPE_P (*tp))
+ *walk_subtrees = false;
+ else if (volatile_lvalue_p (*tp)
+ && !d->saw_volatile)
{
d->saw_volatile = 1;
- error_at (gimple_location (d->stmt),
- "invalid volatile use of %qD inside transaction",
- *tp);
+ if (d->block_flags & DIAG_TM_SAFE)
+ error_at (gimple_location (d->stmt),
+ "invalid use of volatile lvalue inside transaction");
+ else if (d->func_flags & DIAG_TM_SAFE)
+ error_at (gimple_location (d->stmt),
+ "invalid use of volatile lvalue inside %<transaction_safe%>"
+ "function");
}
return NULL_TREE;
@@ -4298,7 +4302,7 @@ ipa_tm_scan_irr_block (basic_block bb)
{
tree lhs = gimple_assign_lhs (stmt);
tree rhs = gimple_assign_rhs1 (stmt);
- if (volatile_var_p (lhs) || volatile_var_p (rhs))
+ if (volatile_lvalue_p (lhs) || volatile_lvalue_p (rhs))
return true;
}
break;
@@ -4306,7 +4310,7 @@ ipa_tm_scan_irr_block (basic_block bb)
case GIMPLE_CALL:
{
tree lhs = gimple_call_lhs (stmt);
- if (lhs && volatile_var_p (lhs))
+ if (lhs && volatile_lvalue_p (lhs))
return true;
if (is_tm_pure_call (stmt))