diff options
author | Richard Guenther <rguenther@suse.de> | 2008-01-16 09:44:23 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2008-01-16 09:44:23 +0000 |
commit | eb1387a0511b0b71c901c7a9458cea1cc2f911c4 (patch) | |
tree | 4a6974a6ea8f6fdba10c4b24af2794548a43d1dd /gcc | |
parent | 4349e292879d8bc589a8a2b52defe5e754d75a16 (diff) | |
download | gcc-eb1387a0511b0b71c901c7a9458cea1cc2f911c4.zip gcc-eb1387a0511b0b71c901c7a9458cea1cc2f911c4.tar.gz gcc-eb1387a0511b0b71c901c7a9458cea1cc2f911c4.tar.bz2 |
re PR c/34768 (Wrong code with conditional function invocation)
2008-01-16 Richard Guenther <rguenther@suse.de>
PR c/34768
* c-typeck.c (common_pointer_type): Do not merge inconsistent
type qualifiers for function types.
* gcc.c-torture/execute/pr34768-1.c: New testcase.
* gcc.c-torture/execute/pr34768-2.c: Likewise.
From-SVN: r131568
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/c-typeck.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr34768-1.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/execute/pr34768-2.c | 28 |
5 files changed, 76 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 90e422e..dd099a4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-01-16 Richard Guenther <rguenther@suse.de> + + PR c/34768 + * c-typeck.c (common_pointer_type): Do not merge inconsistent + type qualifiers for function types. + 2008-01-15 Sebastian Pop <sebastian.pop@amd.com> * tree-parloops (gen_parallel_loop): Revert my fix. diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 6d94cab..fb2e47f 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -530,6 +530,7 @@ common_pointer_type (tree t1, tree t2) tree pointed_to_1, mv1; tree pointed_to_2, mv2; tree target; + unsigned target_quals; /* Save time if the two types are the same. */ @@ -557,10 +558,15 @@ common_pointer_type (tree t1, tree t2) if (TREE_CODE (mv2) != ARRAY_TYPE) mv2 = TYPE_MAIN_VARIANT (pointed_to_2); target = composite_type (mv1, mv2); - t1 = build_pointer_type (c_build_qualified_type - (target, - TYPE_QUALS (pointed_to_1) | - TYPE_QUALS (pointed_to_2))); + + /* For function types do not merge const qualifiers, but drop them + if used inconsistently. The middle-end uses these to mark const + and noreturn functions. */ + if (TREE_CODE (pointed_to_1) == FUNCTION_TYPE) + target_quals = TYPE_QUALS (pointed_to_1) & TYPE_QUALS (pointed_to_2); + else + target_quals = TYPE_QUALS (pointed_to_1) | TYPE_QUALS (pointed_to_2); + t1 = build_pointer_type (c_build_qualified_type (target, target_quals)); return build_type_attribute_variant (t1, attributes); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7a2d834..b69ff98 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-01-16 Richard Guenther <rguenther@suse.de> + + PR c/34768 + * gcc.c-torture/execute/pr34768-1.c: New testcase. + * gcc.c-torture/execute/pr34768-2.c: Likewise. + 2008-01-16 Tobias Burnus <burnus@net-b.de> PR fortran/34796 diff --git a/gcc/testsuite/gcc.c-torture/execute/pr34768-1.c b/gcc/testsuite/gcc.c-torture/execute/pr34768-1.c new file mode 100644 index 0000000..eb16adb --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr34768-1.c @@ -0,0 +1,26 @@ +int x; + +void __attribute__((noinline)) foo (void) +{ + x = -x; +} +void __attribute__((const,noinline)) bar (void) +{ +} + +int __attribute__((noinline)) +test (int c) +{ + int tmp = x; + (c ? foo : bar) (); + return tmp + x; +} + +extern void abort (void); +int main() +{ + x = 1; + if (test (1) != 0) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr34768-2.c b/gcc/testsuite/gcc.c-torture/execute/pr34768-2.c new file mode 100644 index 0000000..917bf9e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr34768-2.c @@ -0,0 +1,28 @@ +int x; + +int __attribute__((noinline)) foo (void) +{ + x = -x; + return 0; +} +int __attribute__((const,noinline)) bar (void) +{ + return 0; +} + +int __attribute__((noinline)) +test (int c) +{ + int tmp = x; + int res = (c ? foo : bar) (); + return tmp + x + res; +} + +extern void abort (void); +int main() +{ + x = 1; + if (test (1) != 0) + abort (); + return 0; +} |