From 0bcdfea9041f7d7a2c7ed642e53b2a5bc43a37a5 Mon Sep 17 00:00:00 2001 From: Ben Langmuir <blangmuir@apple.com> Date: Fri, 11 Dec 2015 22:05:13 +0000 Subject: [PATCH] Reapply "[Modules] Fix regression when an elaborated-type-specifier mentions a hidden tag" Now not trying to use a C++ lookup mechanism in C (d'oh). Unqualified lookup is actually fine for this case in C. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@255377 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 7 +++++++ test/Modules/Inputs/elaborated-type-structs.h | 3 +++ test/Modules/Inputs/module.map | 7 +++++++ ...borated-type-specifier-from-hidden-module.m | 18 ++++++++++++++++++ 4 files changed, 35 insertions(+) create mode 100644 test/Modules/Inputs/elaborated-type-structs.h create mode 100644 test/Modules/elaborated-type-specifier-from-hidden-module.m diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 6a61ac0e44c..f9c1a014260 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -12136,9 +12136,16 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, // In C++, we need to do a redeclaration lookup to properly // diagnose some problems. + // FIXME: redeclaration lookup is also used (with and without C++) to find a + // hidden declaration so that we don't get ambiguity errors when using a + // 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) { Previous.setRedeclarationKind(ForRedeclaration); LookupQualifiedName(Previous, SearchDC); + } else { + Previous.setRedeclarationKind(ForRedeclaration); + LookupName(Previous, S); } } diff --git a/test/Modules/Inputs/elaborated-type-structs.h b/test/Modules/Inputs/elaborated-type-structs.h new file mode 100644 index 00000000000..da3940998fd --- /dev/null +++ b/test/Modules/Inputs/elaborated-type-structs.h @@ -0,0 +1,3 @@ +struct S1; +struct S2 { int x; }; +struct S3 { int x; }; diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map index 226d45fdf44..632517dd363 100644 --- a/test/Modules/Inputs/module.map +++ b/test/Modules/Inputs/module.map @@ -386,3 +386,10 @@ module TypedefTag { header "typedef-tag-hidden.h" } } + +module ElaboratedTypeStructs { + module Empty {} + module Structs { + header "elaborated-type-structs.h" + } +} diff --git a/test/Modules/elaborated-type-specifier-from-hidden-module.m b/test/Modules/elaborated-type-specifier-from-hidden-module.m new file mode 100644 index 00000000000..0ca1c24bba0 --- /dev/null +++ b/test/Modules/elaborated-type-specifier-from-hidden-module.m @@ -0,0 +1,18 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs %s -verify + +@import ElaboratedTypeStructs.Empty; // The structs are now hidden. +struct S1 *x; +struct S2 *y; +// FIXME: compatible definition should not be an error. +struct S2 { int x; }; // expected-error {{redefinition}} +struct S3 *z; +// Incompatible definition. +struct S3 { float y; }; // expected-error {{redefinition}} +// expected-note@elaborated-type-structs.h:* 2 {{previous definition is here}} + +@import ElaboratedTypeStructs.Structs; + +void useS1(struct S1 *x); +void useS2(struct S2 *x); +void useS2(struct S2 *x); -- GitLab