[ASTImporter][AST] Fix structural equivalency crash on dependent FieldDecl
Differential Revision: https://reviews.llvm.org/D88665
This commit is contained in:
parent
707c3d4d42
commit
007dd12d54
|
|
@ -1256,48 +1256,9 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (Field1->isBitField() != Field2->isBitField()) {
|
||||
if (Context.Complain) {
|
||||
Context.Diag2(
|
||||
Owner2->getLocation(),
|
||||
Context.getApplicableDiagnostic(diag::err_odr_tag_type_inconsistent))
|
||||
<< Context.ToCtx.getTypeDeclType(Owner2);
|
||||
if (Field1->isBitField()) {
|
||||
Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
|
||||
<< Field1->getDeclName() << Field1->getType()
|
||||
<< Field1->getBitWidthValue(Context.FromCtx);
|
||||
Context.Diag2(Field2->getLocation(), diag::note_odr_not_bit_field)
|
||||
<< Field2->getDeclName();
|
||||
} else {
|
||||
Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
|
||||
<< Field2->getDeclName() << Field2->getType()
|
||||
<< Field2->getBitWidthValue(Context.ToCtx);
|
||||
Context.Diag1(Field1->getLocation(), diag::note_odr_not_bit_field)
|
||||
<< Field1->getDeclName();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Field1->isBitField()) {
|
||||
// Make sure that the bit-fields are the same length.
|
||||
unsigned Bits1 = Field1->getBitWidthValue(Context.FromCtx);
|
||||
unsigned Bits2 = Field2->getBitWidthValue(Context.ToCtx);
|
||||
|
||||
if (Bits1 != Bits2) {
|
||||
if (Context.Complain) {
|
||||
Context.Diag2(Owner2->getLocation(),
|
||||
Context.getApplicableDiagnostic(
|
||||
diag::err_odr_tag_type_inconsistent))
|
||||
<< Context.ToCtx.getTypeDeclType(Owner2);
|
||||
Context.Diag2(Field2->getLocation(), diag::note_odr_bit_field)
|
||||
<< Field2->getDeclName() << Field2->getType() << Bits2;
|
||||
Context.Diag1(Field1->getLocation(), diag::note_odr_bit_field)
|
||||
<< Field1->getDeclName() << Field1->getType() << Bits1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (Field1->isBitField())
|
||||
return IsStructurallyEquivalent(Context, Field1->getBitWidth(),
|
||||
Field2->getBitWidth());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,16 +21,6 @@
|
|||
// CHECK: struct1.c:27:8: note: no corresponding field here
|
||||
// CHECK: struct2.c:24:31: warning: external variable 'x4' declared with incompatible types in different translation units ('struct S4' vs. 'struct S4')
|
||||
// CHECK: struct1.c:27:22: note: declared here with type 'struct S4'
|
||||
// CHECK: struct1.c:33:8: warning: type 'struct S6' has incompatible definitions in different translation units
|
||||
// CHECK: struct1.c:33:33: note: bit-field 'j' with type 'unsigned int' and length 8 here
|
||||
// CHECK: struct2.c:30:33: note: field 'j' is not a bit-field
|
||||
// CHECK: struct2.c:30:38: warning: external variable 'x6' declared with incompatible types in different translation units ('struct S6' vs. 'struct S6')
|
||||
// CHECK: struct1.c:33:42: note: declared here with type 'struct S6'
|
||||
// CHECK: struct1.c:36:8: warning: type 'struct S7' has incompatible definitions in different translation units
|
||||
// CHECK: struct1.c:36:33: note: bit-field 'j' with type 'unsigned int' and length 8 here
|
||||
// CHECK: struct2.c:33:33: note: bit-field 'j' with type 'unsigned int' and length 16 here
|
||||
// CHECK: struct2.c:33:43: warning: external variable 'x7' declared with incompatible types in different translation units ('struct S7' vs. 'struct S7')
|
||||
// CHECK: struct1.c:36:42: note: declared here with type 'struct S7'
|
||||
// CHECK: struct1.c:56:10: warning: type 'struct DeeperError' has incompatible definitions in different translation units
|
||||
// CHECK: struct1.c:56:35: note: field 'f' has type 'int' here
|
||||
// CHECK: struct2.c:53:37: note: field 'f' has type 'float' here
|
||||
|
|
@ -52,4 +42,4 @@
|
|||
// CHECK: struct2.c:129:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]struct2.c:127:7)' here
|
||||
// CHECK: struct2.c:138:3: warning: external variable 'x16' declared with incompatible types in different translation units ('struct DeepUnnamedError' vs. 'struct DeepUnnamedError')
|
||||
// CHECK: struct1.c:141:3: note: declared here with type 'struct DeepUnnamedError'
|
||||
// CHECK: 20 warnings generated
|
||||
// CHECK: 17 warnings generated
|
||||
|
|
|
|||
|
|
@ -976,6 +976,39 @@ TEST_F(StructuralEquivalenceTemplateTest, DifferentTemplateArgKind) {
|
|||
EXPECT_FALSE(testStructuralMatch(t));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceTemplateTest, BitFieldDecl) {
|
||||
const char *Code = "class foo { int a : 2; };";
|
||||
auto t = makeNamedDecls(Code, Code, Lang_CXX03);
|
||||
EXPECT_TRUE(testStructuralMatch(t));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceTemplateTest, BitFieldDeclDifferentWidth) {
|
||||
auto t = makeNamedDecls("class foo { int a : 2; };",
|
||||
"class foo { int a : 4; };", Lang_CXX03);
|
||||
EXPECT_FALSE(testStructuralMatch(t));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDecl) {
|
||||
const char *Code = "template <class T> class foo { int a : sizeof(T); };";
|
||||
auto t = makeNamedDecls(Code, Code, Lang_CXX03);
|
||||
EXPECT_TRUE(testStructuralMatch(t));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal) {
|
||||
auto t = makeNamedDecls(
|
||||
"template <class A, class B> class foo { int a : sizeof(A); };",
|
||||
"template <class A, class B> class foo { int a : sizeof(B); };",
|
||||
Lang_CXX03);
|
||||
EXPECT_FALSE(testStructuralMatch(t));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceTemplateTest, DependentBitFieldDeclDifferentVal2) {
|
||||
auto t = makeNamedDecls(
|
||||
"template <class A> class foo { int a : sizeof(A); };",
|
||||
"template <class A> class foo { int a : sizeof(A) + 1; };", Lang_CXX03);
|
||||
EXPECT_FALSE(testStructuralMatch(t));
|
||||
}
|
||||
|
||||
TEST_F(StructuralEquivalenceTemplateTest, ExplicitBoolSame) {
|
||||
auto Decls = makeNamedDecls(
|
||||
"template <bool b> struct foo {explicit(b) foo(int);};",
|
||||
|
|
|
|||
Loading…
Reference in New Issue