mirror of https://github.com/microsoft/clang.git
[modules] PR28812: Modules can return duplicate field decls.
If two modules contain duplicate class definitions the lookup result can contain more than 2 elements. Sift the lookup results until we find a field decl. It is not necessary to do ODR checks in place as they done elsewhere. This should fix issues when compiling with libstdc++ 5.2 and 6.2. Patch developed in collaboration with Richard Smith! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@285184 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c9824955f1
commit
f16d077f5a
|
@ -12321,13 +12321,20 @@ ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) {
|
||||||
// Lookup can return at most two results: the pattern for the field, or the
|
// Lookup can return at most two results: the pattern for the field, or the
|
||||||
// injected class name of the parent record. No other member can have the
|
// injected class name of the parent record. No other member can have the
|
||||||
// same name as the field.
|
// same name as the field.
|
||||||
assert(!Lookup.empty() && Lookup.size() <= 2 &&
|
// In modules mode, lookup can return multiple results (coming from
|
||||||
|
// different modules).
|
||||||
|
assert((getLangOpts().Modules || (!Lookup.empty() && Lookup.size() <= 2)) &&
|
||||||
"more than two lookup results for field name");
|
"more than two lookup results for field name");
|
||||||
FieldDecl *Pattern = dyn_cast<FieldDecl>(Lookup[0]);
|
FieldDecl *Pattern = dyn_cast<FieldDecl>(Lookup[0]);
|
||||||
if (!Pattern) {
|
if (!Pattern) {
|
||||||
assert(isa<CXXRecordDecl>(Lookup[0]) &&
|
assert(isa<CXXRecordDecl>(Lookup[0]) &&
|
||||||
"cannot have other non-field member with same name");
|
"cannot have other non-field member with same name");
|
||||||
Pattern = cast<FieldDecl>(Lookup[1]);
|
for (auto L : Lookup)
|
||||||
|
if (isa<FieldDecl>(L)) {
|
||||||
|
Pattern = cast<FieldDecl>(L);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(Pattern && "We must have set the Pattern!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (InstantiateInClassInitializer(Loc, Field, Pattern,
|
if (InstantiateInClassInitializer(Loc, Field, Pattern,
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef T_H
|
||||||
|
#define T_H
|
||||||
|
|
||||||
|
template <typename ValueType> struct VarStreamArray;
|
||||||
|
|
||||||
|
template <typename ValueType> struct VarStreamArrayIterator {
|
||||||
|
VarStreamArrayIterator(VarStreamArray<ValueType>) {}
|
||||||
|
bool HasError{};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // T_H
|
|
@ -0,0 +1 @@
|
||||||
|
#include "Textual.h"
|
|
@ -0,0 +1 @@
|
||||||
|
#include "Textual.h"
|
|
@ -0,0 +1,6 @@
|
||||||
|
module "A" {
|
||||||
|
header "a.h"
|
||||||
|
}
|
||||||
|
module "B" {
|
||||||
|
header "b.h"
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
// RUN: rm -rf %t
|
||||||
|
// RUN: %clang_cc1 -std=c++11 -nostdsysteminc -I%S/Inputs/PR28812 -verify %s
|
||||||
|
// RUN: %clang_cc1 -std=c++11 -nostdsysteminc -fmodules -fimplicit-module-maps \
|
||||||
|
// RUN: -fmodules-cache-path=%t -I%S/Inputs/PR28812 -verify %s
|
||||||
|
|
||||||
|
template <typename> struct VarStreamArrayIterator;
|
||||||
|
template <typename ValueType>
|
||||||
|
struct VarStreamArray {
|
||||||
|
typedef VarStreamArrayIterator<ValueType> Iterator;
|
||||||
|
Iterator begin() { return Iterator(*this); }
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "Textual.h"
|
||||||
|
|
||||||
|
#include "a.h"
|
||||||
|
#include "b.h"
|
||||||
|
|
||||||
|
VarStreamArray<int> a;
|
||||||
|
auto b = a.begin();
|
||||||
|
|
||||||
|
// expected-no-diagnostics
|
||||||
|
|
Loading…
Reference in New Issue