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