forked from OSchip/llvm-project
[ODRHash] Add handling of bitfields
Differential Revision: https://reviews.llvm.org/D21675 llvm-svn: 296170
This commit is contained in:
parent
68ea9aa23a
commit
93772fcfc7
|
@ -133,14 +133,20 @@ def err_module_odr_violation_mismatch_decl_diff : Error<
|
|||
"static assert with condition|"
|
||||
"static assert with message|"
|
||||
"static assert with %select{|no }4message|"
|
||||
"field %4|field %4 with type %5}3">;
|
||||
"field %4|"
|
||||
"field %4 with type %5|"
|
||||
"%select{non-|}5bitfield %4|"
|
||||
"bitfield %4 with one width expression}3">;
|
||||
|
||||
def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
|
||||
"%select{"
|
||||
"static assert with different condition|"
|
||||
"static assert with different message|"
|
||||
"static assert with %select{|no }2message|"
|
||||
"field %2|field %2 with type %3}1">;
|
||||
"field %2|"
|
||||
"field %2 with type %3|"
|
||||
"%select{non-|}3bitfield %2|"
|
||||
"bitfield %2 with different width expression}1">;
|
||||
|
||||
def warn_module_uses_date_time : Warning<
|
||||
"%select{precompiled header|module}0 uses __DATE__ or __TIME__">,
|
||||
|
|
|
@ -183,6 +183,13 @@ public:
|
|||
|
||||
void VisitFieldDecl(const FieldDecl *D) {
|
||||
Inherited::VisitFieldDecl(D);
|
||||
|
||||
const bool IsBitfield = D->isBitField();
|
||||
Hash.AddBoolean(IsBitfield);
|
||||
|
||||
if (IsBitfield) {
|
||||
AddStmt(D->getBitWidth());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -9063,6 +9063,8 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
StaticAssertOnlyMessage,
|
||||
FieldName,
|
||||
FieldTypeName,
|
||||
FieldSingleBitField,
|
||||
FieldDifferentWidthBitField
|
||||
};
|
||||
|
||||
// These lambdas have the common portions of the ODR diagnostics. This
|
||||
|
@ -9213,6 +9215,30 @@ void ASTReader::diagnoseOdrViolations() {
|
|||
}
|
||||
}
|
||||
|
||||
const bool IsFirstBitField = FirstField->isBitField();
|
||||
const bool IsSecondBitField = SecondField->isBitField();
|
||||
if (IsFirstBitField != IsSecondBitField) {
|
||||
ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
|
||||
FieldSingleBitField)
|
||||
<< FirstII << IsFirstBitField;
|
||||
ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
|
||||
FieldSingleBitField)
|
||||
<< SecondII << IsSecondBitField;
|
||||
Diagnosed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (IsFirstBitField && IsSecondBitField) {
|
||||
ODRDiagError(FirstField->getLocation(), FirstField->getSourceRange(),
|
||||
FieldDifferentWidthBitField)
|
||||
<< FirstII << FirstField->getBitWidth()->getSourceRange();
|
||||
ODRDiagNote(SecondField->getLocation(), SecondField->getSourceRange(),
|
||||
FieldDifferentWidthBitField)
|
||||
<< SecondII << SecondField->getBitWidth()->getSourceRange();
|
||||
Diagnosed = true;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,6 +191,47 @@ S5 s5;
|
|||
// expected-note@first.h:* {{but in 'FirstModule' found field 'x' with type 'A' (aka 'int')}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S6 {
|
||||
unsigned x;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S6 {
|
||||
unsigned x : 1;
|
||||
};
|
||||
#else
|
||||
S6 s6;
|
||||
// expected-error@second.h:* {{'Field::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x'}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found non-bitfield 'x'}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S7 {
|
||||
unsigned x : 2;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S7 {
|
||||
unsigned x : 1;
|
||||
};
|
||||
#else
|
||||
S7 s7;
|
||||
// expected-error@second.h:* {{'Field::S7' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}}
|
||||
#endif
|
||||
|
||||
#if defined(FIRST)
|
||||
struct S8 {
|
||||
unsigned x : 2;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
struct S8 {
|
||||
unsigned x : 1 + 1;
|
||||
};
|
||||
#else
|
||||
S8 s8;
|
||||
// expected-error@second.h:* {{'Field::S8' has different definitions in different modules; first difference is definition in module 'SecondModule' found bitfield 'x' with one width expression}}
|
||||
// expected-note@first.h:* {{but in 'FirstModule' found bitfield 'x' with different width expression}}
|
||||
#endif
|
||||
|
||||
} // namespace Field
|
||||
|
||||
|
@ -236,6 +277,9 @@ struct S {
|
|||
double y;
|
||||
|
||||
INT z;
|
||||
|
||||
unsigned a : 1;
|
||||
unsigned b : 2*2 + 5/2;
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
typedef int INT;
|
||||
|
@ -251,6 +295,9 @@ struct S {
|
|||
double y;
|
||||
|
||||
INT z;
|
||||
|
||||
unsigned a : 1;
|
||||
unsigned b : 2 * 2 + 5 / 2;
|
||||
};
|
||||
#else
|
||||
S s;
|
||||
|
@ -271,6 +318,9 @@ struct T {
|
|||
|
||||
INT z;
|
||||
|
||||
unsigned a : 1;
|
||||
unsigned b : 2 * 2 + 5 / 2;
|
||||
|
||||
private:
|
||||
};
|
||||
#elif defined(SECOND)
|
||||
|
@ -288,6 +338,9 @@ struct T {
|
|||
|
||||
INT z;
|
||||
|
||||
unsigned a : 1;
|
||||
unsigned b : 2 * 2 + 5 / 2;
|
||||
|
||||
public:
|
||||
};
|
||||
#else
|
||||
|
|
Loading…
Reference in New Issue