[clang] 09abece - PR48002: Fix injection of elaborated-type-specifiers within local

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Wed Oct 28 14:29:57 PDT 2020


Author: Richard Smith
Date: 2020-10-28T14:29:45-07:00
New Revision: 09abecef7bbfda18d34f046954eaa4d491062839

URL: https://github.com/llvm/llvm-project/commit/09abecef7bbfda18d34f046954eaa4d491062839
DIFF: https://github.com/llvm/llvm-project/commit/09abecef7bbfda18d34f046954eaa4d491062839.diff

LOG: PR48002: Fix injection of elaborated-type-specifiers within local
classes into the enclosing block scope.

We weren't properly detecting whether the name would be injected into a
block scope in the case where it was lexically declared in a local
class.

Added: 
    clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p7.cpp

Modified: 
    clang/lib/Sema/SemaDecl.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2bffd2a87d08..10c9db073a25 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1478,10 +1478,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext) {
 
   // Out-of-line definitions shouldn't be pushed into scope in C++, unless they
   // are function-local declarations.
-  if (getLangOpts().CPlusPlus && D->isOutOfLine() &&
-      !D->getDeclContext()->getRedeclContext()->Equals(
-        D->getLexicalDeclContext()->getRedeclContext()) &&
-      !D->getLexicalDeclContext()->isFunctionOrMethod())
+  if (getLangOpts().CPlusPlus && D->isOutOfLine() && !S->getFnParent())
     return;
 
   // Template instantiations should also not be pushed into scope.
@@ -15728,6 +15725,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
     // type declared by an elaborated-type-specifier.  In C that is not correct
     // and we should instead merge compatible types found by lookup.
     if (getLangOpts().CPlusPlus) {
+      // FIXME: This can perform qualified lookups into function contexts,
+      // which are meaningless.
       Previous.setRedeclarationKind(forRedeclarationInCurContext());
       LookupQualifiedName(Previous, SearchDC);
     } else {

diff  --git a/clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p7.cpp b/clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p7.cpp
new file mode 100644
index 000000000000..fe4f42a8bdb1
--- /dev/null
+++ b/clang/test/CXX/basic/basic.scope/basic.scope.pdecl/p7.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -verify %s
+
+// Some of the diagnostics produce 'did you mean?' suggestions. We don't care
+// which ones for the purpose of this test.
+// expected-note@* 0+{{here}}
+
+struct A *f();
+using Test_A = A;
+
+void f(struct B*);
+using Test_B = B;
+
+struct C;
+using Test_C = C;
+
+struct X {
+  struct D *f();
+  void f(struct E*);
+  struct F;
+  friend struct G;
+};
+using Test_D = D;
+using Test_XD = X::D; // expected-error {{no type named 'D' in 'X'}}
+using Test_E = E;
+using Test_XE = X::E; // expected-error {{no type named 'E' in 'X'}}
+using Test_F = F; // expected-error {{unknown type name 'F'}}
+using Test_XF = X::F;
+using Test_G = G; // expected-error {{unknown type name 'G'}}
+using Test_XG = X::G; // expected-error {{no type named 'G' in 'X'}}
+
+void g() {
+  {
+    struct X {
+      struct H *f();
+      void f(struct I*);
+      struct J;
+      friend struct K;
+    };
+    using Test_H = H;
+    using Test_XH = X::H; // expected-error {{no type named}}
+    using Test_I = I;
+    using Test_XI = X::I; // expected-error {{no type named}}
+    using Test_J = J; // expected-error {{unknown type name}}
+    using Test_XJ = X::J;
+    using Test_K = K; // expected-error {{unknown type name}}
+    using Test_XK = X::K; // expected-error {{no type named}}
+  }
+  using Test_H = H; // expected-error {{unknown type name}}
+  using Test_I = I; // expected-error {{unknown type name}}
+  using Test_J = J; // expected-error {{unknown type name}}
+  using Test_K = K; // expected-error {{unknown type name}}
+}
+using Test_H = H; // expected-error {{unknown type name}}
+using Test_I = I; // expected-error {{unknown type name}}
+using Test_J = J; // expected-error {{unknown type name}}
+using Test_K = K; // expected-error {{unknown type name}}


        


More information about the cfe-commits mailing list