r298754 - [ODRHash] Add support for array and decayed types.

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Fri Mar 24 17:48:53 PDT 2017


Author: rtrieu
Date: Fri Mar 24 19:48:52 2017
New Revision: 298754

URL: http://llvm.org/viewvc/llvm-project?rev=298754&view=rev
Log:
[ODRHash] Add support for array and decayed types.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
    cfe/trunk/lib/AST/ODRHash.cpp
    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=298754&r1=298753&r2=298754&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Fri Mar 24 19:48:52 2017
@@ -148,7 +148,7 @@ def err_module_odr_violation_mismatch_de
   "method %4 is %select{not const|const}5|"
   "method %4 is %select{not inline|inline}5|"
   "method %4 that has %5 parameter%s5|"
-  "method %4 with %ordinal5 parameter of type %6|"
+  "method %4 with %ordinal5 parameter of type %6%select{| decayed from %8}7|"
   "method %4 with %ordinal5 parameter named %6|"
   "method %4 with %ordinal5 parameter with %select{no |}6default argument|"
   "method %4 with %ordinal5 parameter with default argument}3">;
@@ -173,7 +173,7 @@ def note_module_odr_violation_mismatch_d
   "method %2 is %select{not const|const}3|"
   "method %2 is %select{not inline|inline}3|"
   "method %2 that has %3 parameter%s3|"
-  "method %2 with %ordinal3 parameter of type %4|"
+  "method %2 with %ordinal3 parameter of type %4%select{| decayed from %6}5|"
   "method %2 with %ordinal3 parameter named %4|"
   "method %2 with %ordinal3 parameter with %select{no |}4default argument|"
   "method %2 with %ordinal3 parameter with different default argument}1">;

Modified: cfe/trunk/lib/AST/ODRHash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ODRHash.cpp?rev=298754&r1=298753&r2=298754&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ODRHash.cpp (original)
+++ cfe/trunk/lib/AST/ODRHash.cpp Fri Mar 24 19:48:52 2017
@@ -330,6 +330,10 @@ public:
     Hash.AddQualType(T);
   }
 
+  void VisitQualifiers(Qualifiers Quals) {
+    ID.AddInteger(Quals.getAsOpaqueValue());
+  }
+
   void Visit(const Type *T) {
     ID.AddInteger(T->getTypeClass());
     Inherited::Visit(T);
@@ -337,6 +341,43 @@ public:
 
   void VisitType(const Type *T) {}
 
+  void VisitAdjustedType(const AdjustedType *T) {
+    AddQualType(T->getOriginalType());
+    AddQualType(T->getAdjustedType());
+    VisitType(T);
+  }
+
+  void VisitDecayedType(const DecayedType *T) {
+    AddQualType(T->getDecayedType());
+    AddQualType(T->getPointeeType());
+    VisitAdjustedType(T);
+  }
+
+  void VisitArrayType(const ArrayType *T) {
+    AddQualType(T->getElementType());
+    ID.AddInteger(T->getSizeModifier());
+    VisitQualifiers(T->getIndexTypeQualifiers());
+    VisitType(T);
+  }
+  void VisitConstantArrayType(const ConstantArrayType *T) {
+    T->getSize().Profile(ID);
+    VisitArrayType(T);
+  }
+
+  void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
+    AddStmt(T->getSizeExpr());
+    VisitArrayType(T);
+  }
+
+  void VisitIncompleteArrayType(const IncompleteArrayType *T) {
+    VisitArrayType(T);
+  }
+
+  void VisitVariableArrayType(const VariableArrayType *T) {
+    AddStmt(T->getSizeExpr());
+    VisitArrayType(T);
+  }
+
   void VisitBuiltinType(const BuiltinType *T) {
     ID.AddInteger(T->getKind());
     VisitType(T);

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=298754&r1=298753&r2=298754&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Mar 24 19:48:52 2017
@@ -9586,13 +9586,33 @@ void ASTReader::diagnoseOdrViolations()
         for (unsigned I = 0; I < FirstNumParameters; ++I) {
           const ParmVarDecl *FirstParam = FirstMethod->getParamDecl(I);
           const ParmVarDecl *SecondParam = SecondMethod->getParamDecl(I);
-          if (FirstParam->getType() != SecondParam->getType()) {
-            ODRDiagError(FirstMethod->getLocation(),
-                         FirstMethod->getSourceRange(), MethodParameterType)
-                << FirstName << (I + 1) << FirstParam->getType();
-            ODRDiagNote(SecondMethod->getLocation(),
-                        SecondMethod->getSourceRange(), MethodParameterType)
-                << SecondName << (I + 1) << SecondParam->getType();
+
+          QualType FirstParamType = FirstParam->getType();
+          QualType SecondParamType = SecondParam->getType();
+          if (FirstParamType != SecondParamType) {
+            if (const DecayedType *ParamDecayedType =
+                    FirstParamType->getAs<DecayedType>()) {
+              ODRDiagError(FirstMethod->getLocation(),
+                           FirstMethod->getSourceRange(), MethodParameterType)
+                  << FirstName << (I + 1) << FirstParamType << true
+                  << ParamDecayedType->getOriginalType();
+            } else {
+              ODRDiagError(FirstMethod->getLocation(),
+                           FirstMethod->getSourceRange(), MethodParameterType)
+                  << FirstName << (I + 1) << FirstParamType << false;
+            }
+
+            if (const DecayedType *ParamDecayedType =
+                    SecondParamType->getAs<DecayedType>()) {
+              ODRDiagNote(SecondMethod->getLocation(),
+                          SecondMethod->getSourceRange(), MethodParameterType)
+                  << SecondName << (I + 1) << SecondParamType << true
+                  << ParamDecayedType->getOriginalType();
+            } else {
+              ODRDiagNote(SecondMethod->getLocation(),
+                          SecondMethod->getSourceRange(), MethodParameterType)
+                  << SecondName << (I + 1) << SecondParamType << false;
+            }
             ParameterMismatch = true;
             break;
           }

Modified: cfe/trunk/test/Modules/odr_hash.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.cpp?rev=298754&r1=298753&r2=298754&view=diff
==============================================================================
--- cfe/trunk/test/Modules/odr_hash.cpp (original)
+++ cfe/trunk/test/Modules/odr_hash.cpp Fri Mar 24 19:48:52 2017
@@ -275,6 +275,33 @@ S11 s11;
 // expected-note at first.h:* {{but in 'FirstModule' found field 'x' with a different initializer}}
 #endif
 
+#if defined(FIRST)
+struct S12 {
+  unsigned x[5];
+};
+#elif defined(SECOND)
+struct S12 {
+  unsigned x[7];
+};
+#else
+S12 s12;
+// expected-error at first.h:* {{'Field::S12::x' from module 'FirstModule' is not present in definition of 'Field::S12' in module 'SecondModule'}}
+// expected-note at second.h:* {{declaration of 'x' does not match}}
+#endif
+
+#if defined(FIRST)
+struct S13 {
+  unsigned x[7];
+};
+#elif defined(SECOND)
+struct S13 {
+  double x[7];
+};
+#else
+S13 s13;
+// expected-error at first.h:* {{'Field::S13::x' from module 'FirstModule' is not present in definition of 'Field::S13' in module 'SecondModule'}}
+// expected-note at second.h:* {{declaration of 'x' does not match}}
+#endif
 }  // namespace Field
 
 namespace Method {
@@ -476,6 +503,20 @@ S13 s13;
 // expected-error at second.h:* {{'Method::S13' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter with default argument}}
 // expected-note at first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter with different default argument}}
 #endif
+
+#if defined(FIRST)
+struct S14 {
+  void A(int x[2]) {}
+};
+#elif defined(SECOND)
+struct S14 {
+  void A(int x[3]) {}
+};
+#else
+S14 s14;
+// expected-error at second.h:* {{'Method::S14' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter of type 'int *' decayed from 'int [3]'}}
+// expected-note at first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter of type 'int *' decayed from 'int [2]'}}
+#endif
 }  // namespace Method
 
 // Naive parsing of AST can lead to cycles in processing.  Ensure
@@ -597,74 +638,52 @@ S3 s3;
 
 // Interesting cases that should not cause errors.  struct S should not error
 // while struct T should error at the access specifier mismatch at the end.
+#define ALL_DECLS                                        \
+public:                                                  \
+private:                                                 \
+protected:                                               \
+  static_assert(1 == 1, "Message");                      \
+  static_assert(2 == 2);                                 \
+                                                         \
+  int x;                                                 \
+  double y;                                              \
+                                                         \
+  INT z;                                                 \
+                                                         \
+  unsigned a : 1;                                        \
+  unsigned b : 2 * 2 + 5 / 2;                            \
+                                                         \
+  mutable int c = sizeof(x + y);                         \
+                                                         \
+  void method() {}                                       \
+  static void static_method() {}                         \
+  virtual void virtual_method() {}                       \
+  virtual void pure_virtual_method() = 0;                \
+  inline void inline_method() {}                         \
+  void volatile_method() volatile {}                     \
+  void const_method() const {}                           \
+                                                         \
+  typedef int typedef_int;                               \
+  using using_int = int;                                 \
+                                                         \
+  void method_one_arg(int x) {}                          \
+  void method_one_arg_default_argument(int x = 5 + 5) {} \
+  void method_decayed_type(int x[5]) {}                  \
+                                                         \
+  int constant_arr[5];                                   \
+                                                         \
+  double last_decl;
+
 namespace AllDecls {
 #if defined(FIRST)
 typedef int INT;
 struct S {
-  public:
-  private:
-  protected:
-
-  static_assert(1 == 1, "Message");
-  static_assert(2 == 2);
-
-  int x;
-  double y;
-
-  INT z;
-
-  unsigned a : 1;
-  unsigned b : 2*2 + 5/2;
-
-  mutable int c = sizeof(x + y);
-
-  void method() {}
-  static void static_method() {}
-  virtual void virtual_method() {}
-  virtual void pure_virtual_method() = 0;
-  inline void inline_method() {}
-  void volatile_method() volatile {}
-  void const_method() const {}
-
-  typedef int typedef_int;
-  using using_int = int;
-
-  void method_one_arg(int x) {}
-  void method_one_arg_default_argument(int x = 5 + 5) {}
+  ALL_DECLS
 };
 #elif defined(SECOND)
 typedef int INT;
 struct S {
-  public:
-  private:
-  protected:
-
-  static_assert(1 == 1, "Message");
-  static_assert(2 == 2);
-
-  int x;
-  double y;
-
-  INT z;
-
-  unsigned a : 1;
-  unsigned b : 2 * 2 + 5 / 2;
-
-  mutable int c = sizeof(x + y);
-
-  void method() {}
-  static void static_method() {}
-  virtual void virtual_method() {}
-  virtual void pure_virtual_method() = 0;
-  inline void inline_method() {}
-  void volatile_method() volatile {}
-  void const_method() const {}
-
-  typedef int typedef_int;
-  using using_int = int;
-
-  void method_one_arg(int x) {}
-  void method_one_arg_default_argument(int x = 5 + 5) {}
+  ALL_DECLS
 };
 #else
 S *s;
@@ -673,72 +692,14 @@ S *s;
 #if defined(FIRST)
 typedef int INT;
 struct T {
-  public:
-  private:
-  protected:
-
-  static_assert(1 == 1, "Message");
-  static_assert(2 == 2);
-
-  int x;
-  double y;
-
-  INT z;
-
-  unsigned a : 1;
-  unsigned b : 2 * 2 + 5 / 2;
-
-  mutable int c = sizeof(x + y);
-
-  void method() {}
-  static void static_method() {}
-  virtual void virtual_method() {}
-  virtual void pure_virtual_method() = 0;
-  inline void inline_method() {}
-  void volatile_method() volatile {}
-  void const_method() const {}
-
-  typedef int typedef_int;
-  using using_int = int;
-
-  void method_one_arg(int x) {}
-  void method_one_arg_default_argument(int x = 5 + 5) {}
+  ALL_DECLS
 
   private:
 };
 #elif defined(SECOND)
 typedef int INT;
 struct T {
-  public:
-  private:
-  protected:
-
-  static_assert(1 == 1, "Message");
-  static_assert(2 == 2);
-
-  int x;
-  double y;
-
-  INT z;
-
-  unsigned a : 1;
-  unsigned b : 2 * 2 + 5 / 2;
-
-  mutable int c = sizeof(x + y);
-
-  void method() {}
-  static void static_method() {}
-  virtual void virtual_method() {}
-  virtual void pure_virtual_method() = 0;
-  inline void inline_method() {}
-  void volatile_method() volatile {}
-  void const_method() const {}
-
-  typedef int typedef_int;
-  using using_int = int;
-
-  void method_one_arg(int x) {}
-  void method_one_arg_default_argument(int x = 5 + 5) {}
+  ALL_DECLS
 
   public:
 };




More information about the cfe-commits mailing list