summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2015-09-29 14:43:08 -0400
committerJason Merrill <jason@redhat.com>2015-09-29 23:20:59 -0400
commitc3a555ab442a28d724c90c3e0e2218e0b71dda1c (patch)
tree104bd07136ef506fc1c429e6e79d3dd38faa86dd
parentce4c7a0c87c166139b4ad33eee0e0d6aa48905f8 (diff)
downloadgcc-jason/tm.tar.gz
Diagnose volatile accesses in transaction_safe function.jason/tm
* trans-mem.c (volatile_lvalue_p): Rename from volatile_var_p. (diagnose_tm_1_op): Also diagnose volatile accesses in transaction_safe function.
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/tm/unsafe1a.C9
-rw-r--r--gcc/trans-mem.c27
3 files changed, 31 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8d55423390e..2505fa48d44 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2015-09-29 Jason Merrill <jason@redhat.com>
+
+ * trans-mem.c (volatile_lvalue_p): Rename from volatile_var_p.
+ (diagnose_tm_1_op): Also diagnose volatile accesses in
+ transaction_safe function.
+
2015-09-29 Jeff Law <law@redhat.com>
* config/microblaze/microblaze.c (microblaze_version_to_int): Remove
diff --git a/gcc/testsuite/g++.dg/tm/unsafe1a.C b/gcc/testsuite/g++.dg/tm/unsafe1a.C
new file mode 100644
index 00000000000..f4d6eba22d9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/unsafe1a.C
@@ -0,0 +1,9 @@
+// Transaction-unsafe testcase from TM TS.
+// { dg-options -fgnu-tm }
+
+volatile int * p = 0;
+int f() transaction_safe {
+ 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/trans-mem.c b/gcc/trans-mem.c
index d9a681f2a34..a73d4bc5daa 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -594,12 +594,12 @@ 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)));
}
@@ -612,14 +612,19 @@ diagnose_tm_1_op (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
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;
@@ -4300,7 +4305,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;
@@ -4308,7 +4313,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))