From eb1387a0511b0b71c901c7a9458cea1cc2f911c4 Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Wed, 16 Jan 2008 09:44:23 +0000 Subject: [PATCH] re PR c/34768 (Wrong code with conditional function invocation) 2008-01-16 Richard Guenther 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 --- gcc/ChangeLog | 6 ++++ gcc/c-typeck.c | 14 +++++++--- gcc/testsuite/ChangeLog | 6 ++++ .../gcc.c-torture/execute/pr34768-1.c | 26 +++++++++++++++++ .../gcc.c-torture/execute/pr34768-2.c | 28 +++++++++++++++++++ 5 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr34768-1.c create mode 100644 gcc/testsuite/gcc.c-torture/execute/pr34768-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 90e422ea130..dd099a44055 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2008-01-16 Richard Guenther + + PR c/34768 + * c-typeck.c (common_pointer_type): Do not merge inconsistent + type qualifiers for function types. + 2008-01-15 Sebastian Pop * tree-parloops (gen_parallel_loop): Revert my fix. diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 6d94cabdf99..fb2e47f0969 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 7a2d834e641..b69ff985439 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2008-01-16 Richard Guenther + + 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 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 00000000000..eb16adbf1f3 --- /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 00000000000..917bf9e2b6f --- /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; +}