forked from OSchip/llvm-project
[ODRHash] Finish FieldDecl support by handling mutable and initializers.
https://reviews.llvm.org/rL296170 llvm-svn: 296198
This commit is contained in:
parent
0d67b10a3c
commit
8d543e2741
|
@ -136,7 +136,10 @@ def err_module_odr_violation_mismatch_decl_diff : Error<
|
|||
"field %4|"
|
||||
"field %4 with type %5|"
|
||||
"%select{non-|}5bitfield %4|"
|
||||
"bitfield %4 with one width expression}3">;
|
||||
"bitfield %4 with one width expression|"
|
||||
"%select{non-|}5mutable field %4|"
|
||||
"field %4 with %select{no|an}5 initalizer|"
|
||||
"field %4 with an initializer}3">;
|
||||
|
||||
def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
|
||||
"%select{"
|
||||
|
@ -146,7 +149,10 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
|
|||
"field %2|"
|
||||
"field %2 with type %3|"
|
||||
"%select{non-|}3bitfield %2|"
|
||||
"bitfield %2 with different width expression}1">;
|
||||
"bitfield %2 with different width expression|"
|
||||
"%select{non-|}3mutable field %2|"
|
||||
"field %2 with %select{no|an}3 initializer|"
|
||||
"field %2 with a different initializer}1">;
|
||||
|
||||
def warn_module_uses_date_time : Warning<
|
||||
"%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
|
||||
|
|
|
@ -190,6 +190,9 @@ public:
|
|||
if (IsBitfield) {
|
||||
AddStmt(D->getBitWidth());
|
||||
}
|
||||
|
||||
Hash.AddBoolean(D->isMutable());
|
||||
AddStmt(D->getInClassInitializer());
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -9064,7 +9064,10 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
FieldName,
|
||||
FieldTypeName,
|
||||
FieldSingleBitField,
|
||||
FieldDifferentWidthBitField
|
||||
FieldDifferentWidthBitField,
|
||||
FieldSingleMutable,
|
||||
FieldSingleInitializer,
|
||||
FieldDifferentInitializers,
|
||||
};
|
||||
|
||||
// These lambdas have the common portions of the ODR diagnostics. This
|
||||
|
@ -9239,6 +9242,50 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
break;
|
||||
}
|
||||
|
||||
const bool IsFirstMutable = FirstField->isMutable();
|
||||
const bool IsSecondMutable = SecondField->isMutable();
|
||||
if (IsFirstMutable != IsSecondMutable) {
|
||||
ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
|
||||
FieldSingleMutable)
|
||||
<< FirstII << IsFirstMutable;
|
||||
ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
|
||||
FieldSingleMutable)
|
||||
<< SecondII << IsSecondMutable;
|
||||
Diagnosed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
const Expr *FirstInitializer = FirstField->getInClassInitializer();
|
||||
const Expr *SecondInitializer = SecondField->getInClassInitializer();
|
||||
if ((!FirstInitializer && SecondInitializer) ||
|
||||
(FirstInitializer && !SecondInitializer)) {
|
||||
ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
|
||||
FieldSingleInitializer)
|
||||
<< FirstII << (FirstInitializer != nullptr);
|
||||
ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
|
||||
FieldSingleInitializer)
|
||||
<< SecondII << (SecondInitializer != nullptr);
|
||||
Diagnosed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (FirstInitializer && SecondInitializer) {
|
||||
unsigned FirstInitHash = ComputeODRHash(FirstInitializer);
|
||||
unsigned SecondInitHash = ComputeODRHash(SecondInitializer);
|
||||
if (FirstInitHash != SecondInitHash) {
|
||||
ODRDiagError(FirstField->getLocation(),
|
||||
FirstField->getSourceRange(),
|
||||
FieldDifferentInitializers)
|
||||
<< FirstII << FirstInitializer->getSourceRange();
|
||||
ODRDiagNote(SecondField->getLocation(),
|
||||
SecondField->getSourceRange(),
|
||||
FieldDifferentInitializers)
|
||||
<< SecondII << SecondInitializer->getSourceRange();
|
||||
Diagnosed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -233,6 +233,48 @@ S8 s8;
|
|||
// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S9 {
|
||||
mutable int x;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S9 {
|
||||
int x;
|
||||
};
|
||||
#else
|
||||
S9 s9;
|
||||
// expected-error@second.h:* {{'Field::S9' has different definitions in different modules; first difference is definition in module 'SecondModule' found non-mutable field 'x'}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found mutable field 'x'}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S10 {
|
||||
unsigned x = 5;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S10 {
|
||||
unsigned x;
|
||||
};
|
||||
#else
|
||||
S10 s10;
|
||||
// expected-error@second.h:* {{'Field::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with no initalizer}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with an initializer}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S11 {
|
||||
unsigned x = 5;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S11 {
|
||||
unsigned x = 7;
|
||||
};
|
||||
#else
|
||||
S11 s11;
|
||||
// expected-error@second.h:* {{'Field::S11' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'x' with an initializer}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}}
|
||||
#endif
|
||||
|
||||
} // namespace Field
|
||||
|
||||
// Naive parsing of AST can lead to cycles in processing. Ensure
|
||||
|
@ -280,6 +322,8 @@ struct S {
|
|||
|
||||
unsigned a : 1;
|
||||
unsigned b : 2*2 + 5/2;
|
||||
|
||||
mutable int c = sizeof(x + y);
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
typedef int INT;
|
||||
|
@ -298,6 +342,8 @@ struct S {
|
|||
|
||||
unsigned a : 1;
|
||||
unsigned b : 2 * 2 + 5 / 2;
|
||||
|
||||
mutable int c = sizeof(x + y);
|
||||
};
|
||||
#else
|
||||
S s;
|
||||
|
@ -321,6 +367,8 @@ struct T {
|
|||
unsigned a : 1;
|
||||
unsigned b : 2 * 2 + 5 / 2;
|
||||
|
||||
mutable int c = sizeof(x + y);
|
||||
|
||||
private:
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
|
@ -341,6 +389,8 @@ struct T {
|
|||
unsigned a : 1;
|
||||
unsigned b : 2 * 2 + 5 / 2;
|
||||
|
||||
mutable int c = sizeof(x + y);
|
||||
|
||||
public:
|
||||
};
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue