diff options
author | Jason Merrill <jason@redhat.com> | 2015-09-29 14:43:08 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2015-09-29 23:20:59 -0400 |
commit | c3a555ab442a28d724c90c3e0e2218e0b71dda1c (patch) | |
tree | 104bd07136ef506fc1c429e6e79d3dd38faa86dd | |
parent | ce4c7a0c87c166139b4ad33eee0e0d6aa48905f8 (diff) | |
download | gcc-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/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tm/unsafe1a.C | 9 | ||||
-rw-r--r-- | gcc/trans-mem.c | 27 |
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)) |