r305238 - [ODRHash] Add diagnostic messages for typedef and type alias.
Richard Trieu via cfe-commits
cfe-commits at lists.llvm.org
Mon Jun 12 14:58:22 PDT 2017
Author: rtrieu
Date: Mon Jun 12 16:58:22 2017
New Revision: 305238
URL: http://llvm.org/viewvc/llvm-project?rev=305238&view=rev
Log:
[ODRHash] Add diagnostic messages for typedef and type alias.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/test/Modules/odr_hash.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=305238&r1=305237&r2=305238&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Mon Jun 12 16:58:22 2017
@@ -121,10 +121,10 @@ def err_module_odr_violation_mismatch_de
"%q0 has different definitions in different modules; first difference is "
"%select{definition in module '%2'|defined here}1 found "
"%select{end of class|public access specifier|private access specifier|"
- "protected access specifier|static assert|field|method}3">;
+ "protected access specifier|static assert|field|method|type alias|typedef}3">;
def note_module_odr_violation_mismatch_decl : Note<"but in '%0' found "
"%select{end of class|public access specifier|private access specifier|"
- "protected access specifier|static assert|field|method}1">;
+ "protected access specifier|static assert|field|method|type alias|typedef}1">;
def err_module_odr_violation_mismatch_decl_diff : Error<
"%q0 has different definitions in different modules; first difference is "
@@ -149,7 +149,9 @@ def err_module_odr_violation_mismatch_de
"method %4 is %select{not inline|inline}5|"
"method %4 that has %5 parameter%s5|"
"method %4 with %ordinal5 parameter of type %6%select{| decayed from %8}7|"
- "method %4 with %ordinal5 parameter named %6}3">;
+ "method %4 with %ordinal5 parameter named %6|"
+ "%select{typedef|type alias}4 name %5|"
+ "%select{typedef|type alias}4 %5 with underlying type %6}3">;
def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
"%select{"
@@ -172,15 +174,19 @@ def note_module_odr_violation_mismatch_d
"method %2 is %select{not inline|inline}3|"
"method %2 that has %3 parameter%s3|"
"method %2 with %ordinal3 parameter of type %4%select{| decayed from %6}5|"
- "method %2 with %ordinal3 parameter named %4}1">;
+ "method %2 with %ordinal3 parameter named %4|"
+ "%select{typedef|type alias}2 name %3|"
+ "%select{typedef|type alias}2 %3 with different underlying type %4}1">;
def err_module_odr_violation_mismatch_decl_unknown : Error<
"%q0 %select{with definition in module '%2'|defined here}1 has different "
"definitions in different modules; first difference is this "
- "%select{||||static assert|field|method|unexpected decl}3">;
+ "%select{||||static assert|field|method|type alias|typedef|"
+ "unexpected decl}3">;
def note_module_odr_violation_mismatch_decl_unknown : Note<
"but in '%0' found "
"%select{||||different static assert|different field|different method|"
+ "different type alias|different typedef|"
"another unexpected decl}1">;
def warn_duplicate_module_file_extension : Warning<
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=305238&r1=305237&r2=305238&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Jun 12 16:58:22 2017
@@ -9242,6 +9242,7 @@ void ASTReader::diagnoseOdrViolations()
// Used with err_module_odr_violation_mismatch_decl and
// note_module_odr_violation_mismatch_decl
+ // This list should be the same Decl's as in ODRHash::isWhiteListedDecl
enum {
EndOfClass,
PublicSpecifer,
@@ -9250,6 +9251,8 @@ void ASTReader::diagnoseOdrViolations()
StaticAssert,
Field,
CXXMethod,
+ TypeAlias,
+ TypeDef,
Other
} FirstDiffType = Other,
SecondDiffType = Other;
@@ -9277,6 +9280,10 @@ void ASTReader::diagnoseOdrViolations()
return Field;
case Decl::CXXMethod:
return CXXMethod;
+ case Decl::TypeAlias:
+ return TypeAlias;
+ case Decl::Typedef:
+ return TypeDef;
}
};
@@ -9373,6 +9380,8 @@ void ASTReader::diagnoseOdrViolations()
MethodNumberParameters,
MethodParameterType,
MethodParameterName,
+ TypedefName,
+ TypedefType,
};
// These lambdas have the common portions of the ODR diagnostics. This
@@ -9748,6 +9757,38 @@ void ASTReader::diagnoseOdrViolations()
break;
}
+ case TypeAlias:
+ case TypeDef: {
+ TypedefNameDecl *FirstTD = cast<TypedefNameDecl>(FirstDecl);
+ TypedefNameDecl *SecondTD = cast<TypedefNameDecl>(SecondDecl);
+ auto FirstName = FirstTD->getDeclName();
+ auto SecondName = SecondTD->getDeclName();
+ if (FirstName != SecondName) {
+ ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(),
+ TypedefName)
+ << (FirstDiffType == TypeAlias) << FirstName;
+ ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(),
+ TypedefName)
+ << (FirstDiffType == TypeAlias) << SecondName;
+ Diagnosed = true;
+ break;
+ }
+
+ QualType FirstType = FirstTD->getUnderlyingType();
+ QualType SecondType = SecondTD->getUnderlyingType();
+ if (ComputeQualTypeODRHash(FirstType) !=
+ ComputeQualTypeODRHash(SecondType)) {
+ ODRDiagError(FirstTD->getLocation(), FirstTD->getSourceRange(),
+ TypedefType)
+ << (FirstDiffType == TypeAlias) << FirstName << FirstType;
+ ODRDiagNote(SecondTD->getLocation(), SecondTD->getSourceRange(),
+ TypedefType)
+ << (FirstDiffType == TypeAlias) << SecondName << SecondType;
+ Diagnosed = true;
+ break;
+ }
+ break;
+ }
}
if (Diagnosed == true)
Modified: cfe/trunk/test/Modules/odr_hash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=305238&r1=305237&r2=305238&view=diff
==============================================================================
--- cfe/trunk/test/Modules/odr_hash.cpp (original)
+++ cfe/trunk/test/Modules/odr_hash.cpp Mon Jun 12 16:58:22 2017
@@ -586,6 +586,57 @@ S3 s3;
// expected-error at first.h:* {{'TypeDef::S3::a' from module 'FirstModule' is not present in definition of 'TypeDef::S3' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'a' does not match}}
#endif
+
+#if defined(FIRST)
+struct S4 {
+ typedef int a;
+ typedef int b;
+};
+#elif defined(SECOND)
+struct S4 {
+ typedef int b;
+ typedef int a;
+};
+#else
+S4 s4;
+// expected-error at second.h:* {{'TypeDef::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef name 'b'}}
+// expected-note at first.h:* {{but in 'FirstModule' found typedef name 'a'}}
+#endif
+
+#if defined(FIRST)
+struct S5 {
+ typedef int a;
+ typedef int b;
+ int x;
+};
+#elif defined(SECOND)
+struct S5 {
+ int x;
+ typedef int b;
+ typedef int a;
+};
+#else
+S5 s5;
+// expected-error at second.h:* {{'TypeDef::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
+// expected-note at first.h:* {{but in 'FirstModule' found typedef}}
+#endif
+
+#if defined(FIRST)
+typedef float F;
+struct S6 {
+ typedef int a;
+ typedef F b;
+};
+#elif defined(SECOND)
+struct S6 {
+ typedef int a;
+ typedef float b;
+};
+#else
+S6 s6;
+// expected-error at second.h:* {{'TypeDef::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef 'b' with underlying type 'float'}}
+// expected-note at first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'TypeDef::F' (aka 'float')}}
+#endif
} // namespace TypeDef
namespace Using {
@@ -632,6 +683,57 @@ S3 s3;
// expected-error at first.h:* {{'Using::S3::a' from module 'FirstModule' is not present in definition of 'Using::S3' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'a' does not match}}
#endif
+
+#if defined(FIRST)
+struct S4 {
+ using a = int;
+ using b = int;
+};
+#elif defined(SECOND)
+struct S4 {
+ using b = int;
+ using a = int;
+};
+#else
+S4 s4;
+// expected-error at second.h:* {{'Using::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias name 'b'}}
+// expected-note at first.h:* {{but in 'FirstModule' found type alias name 'a'}}
+#endif
+
+#if defined(FIRST)
+struct S5 {
+ using a = int;
+ using b = int;
+ int x;
+};
+#elif defined(SECOND)
+struct S5 {
+ int x;
+ using b = int;
+ using a = int;
+};
+#else
+S5 s5;
+// expected-error at second.h:* {{'Using::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found field}}
+// expected-note at first.h:* {{but in 'FirstModule' found type alias}}
+#endif
+
+#if defined(FIRST)
+typedef float F;
+struct S6 {
+ using a = int;
+ using b = F;
+};
+#elif defined(SECOND)
+struct S6 {
+ using a = int;
+ using b = float;
+};
+#else
+S6 s6;
+// expected-error at second.h:* {{'Using::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'b' with underlying type 'float'}}
+// expected-note at first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'Using::F' (aka 'float')}}
+#endif
} // namespace Using
namespace RecordType {
More information about the cfe-commits
mailing list