From 7d67159b48803e2558f33600e2f015f4e251a3e1 Mon Sep 17 00:00:00 2001 From: Ville Voutilainen Date: Fri, 27 May 2016 17:59:01 +0300 Subject: [PATCH] re PR c++/69855 (Missing diagnostic for overload that only differs by return type) /cp PR c++/69855 * name-lookup.c (pushdecl_maybe_friend_1): Push local function decls into the global scope after stripping template bits and setting DECL_ANTICIPATED. /testsuite PR c++/69855 * g++.dg/overload/69855.C: New. * g++.old-deja/g++.law/missed-error2.C: Adjust. * g++.old-deja/g++.pt/crash3.C: Likewise. From-SVN: r236826 --- gcc/cp/ChangeLog | 7 +++ gcc/cp/name-lookup.c | 18 ++++++++ gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/g++.dg/overload/69855.C | 44 +++++++++++++++++++ .../g++.old-deja/g++.law/missed-error2.C | 7 +-- gcc/testsuite/g++.old-deja/g++.pt/crash3.C | 4 +- 6 files changed, 82 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/g++.dg/overload/69855.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 770f817eeca..6c07df156bd 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2016-05-27 Ville Voutilainen + + PR c++/69855 + * name-lookup.c (pushdecl_maybe_friend_1): Push local function + decls into the global scope after stripping template bits + and setting DECL_ANTICIPATED. + 2016-05-26 Jakub Jelinek * semantics.c (finish_omp_clauses) : Warn diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index eb128db5733..568c75e80e4 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -929,6 +929,24 @@ pushdecl_maybe_friend_1 (tree x, bool is_friend) DECL_ANTICIPATED (t) = 1; DECL_HIDDEN_FRIEND_P (t) = 1; } + + if (TREE_CODE (x) == FUNCTION_DECL + && DECL_LOCAL_FUNCTION_P (x) + && !DECL_OMP_DECLARE_REDUCTION_P (x) + && !type_dependent_expression_p (x)) + { + /* PR c++/69855, a local function declaration + is stripped from template info and pushed to + the local scope as a hidden declaration. This + allows ill-formed overloads even in other scopes + to be diagnosed both at the local declaration site + and after it. */ + tree t2 = copy_decl (t); + DECL_USE_TEMPLATE (t2) = 0; + DECL_TEMPLATE_INFO (t2) = NULL_TREE; + DECL_ANTICIPATED (t2) = 1; + push_overloaded_decl (t2, PUSH_GLOBAL, is_friend); + } } if (t != x || DECL_FUNCTION_TEMPLATE_P (t)) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 70b372510a9..00c2a99aaea 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-05-27 Ville Voutilainen + + PR c++/69855 + * g++.dg/overload/69855.C: New. + * g++.old-deja/g++.law/missed-error2.C: Adjust. + * g++.old-deja/g++.pt/crash3.C: Likewise. + 2016-05-27 Jiong Wang PR target/63596 diff --git a/gcc/testsuite/g++.dg/overload/69855.C b/gcc/testsuite/g++.dg/overload/69855.C new file mode 100644 index 00000000000..dc2d7337032 --- /dev/null +++ b/gcc/testsuite/g++.dg/overload/69855.C @@ -0,0 +1,44 @@ +// PR c++/69855 +// { dg-do compile } + +int get(); +void f() { + char get(); // { dg-error "ambiguating" } +} + +int get2(); +char get2(int); +void f2() { + char get2(); // { dg-error "ambiguating" } +} + +char get3(int); +void f3() { + char get3(); +} + +void f4() { + char get4(); +} +int get4(); // { dg-error "ambiguating" } + +void get5(); + +template struct X +{ + void g() + { + int get5(); // { dg-error "ambiguating" } + } +}; + + +template struct X2 +{ + void g() + { + int get6(); + } +}; + +void get6(); // { dg-error "ambiguating" } diff --git a/gcc/testsuite/g++.old-deja/g++.law/missed-error2.C b/gcc/testsuite/g++.old-deja/g++.law/missed-error2.C index 42f70aeb997..26ae87d7a2e 100644 --- a/gcc/testsuite/g++.old-deja/g++.law/missed-error2.C +++ b/gcc/testsuite/g++.old-deja/g++.law/missed-error2.C @@ -25,9 +25,10 @@ int main() { foo(4, -37, 14.39, 14.38); } -// 971006 we no longer give an error for this since we emit a hard error -// about the declaration above -static void foo(int i, int j, double x, double y) { +// 971006 we no longer gave an error for this since we emit a hard error +// about the declaration above, but after the fix for PR c++/69855 +// this declaration emits a diagnostic again +static void foo(int i, int j, double x, double y) { // { dg-error "extern|static" } std::cout << "Max(int): " << max(i,j) << " Max(double): " << max(x,y) << '\n'; diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash3.C b/gcc/testsuite/g++.old-deja/g++.pt/crash3.C index 160cbe541a1..2ba61d9cdb9 100644 --- a/gcc/testsuite/g++.old-deja/g++.pt/crash3.C +++ b/gcc/testsuite/g++.old-deja/g++.pt/crash3.C @@ -10,7 +10,7 @@ public: } CVector g() const { - CVector v(); - return v; + CVector v2(); + return v2; } }; -- 2.30.2