r341013 - Ensure canonical type is actually canonical.

Richard Trieu via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 29 18:57:52 PDT 2018


Author: rtrieu
Date: Wed Aug 29 18:57:52 2018
New Revision: 341013

URL: http://llvm.org/viewvc/llvm-project?rev=341013&view=rev
Log:
Ensure canonical type is actually canonical.

ASTContext::applyObjCProtocolQualifiers will return a canonical type when given
a canonical type and an array of canonical protocols.  If the protocols are not
canonical then the returned type is also not canonical.  Since a canonical type is needed, canonicalize the returned type before using it.  This later prevents
a type from having a non-canonical canonical type.

Added:
    cfe/trunk/test/Modules/odr_hash.mm
Modified:
    cfe/trunk/lib/AST/ASTContext.cpp

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=341013&r1=341012&r2=341013&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Aug 29 18:57:52 2018
@@ -4550,8 +4550,8 @@ ASTContext::getObjCTypeParamType(const O
     if (!protocols.empty()) {
       // Apply the protocol qualifers.
       bool hasError;
-      Canonical = applyObjCProtocolQualifiers(Canonical, protocols, hasError,
-          true/*allowOnPointerType*/);
+      Canonical = getCanonicalType(applyObjCProtocolQualifiers(
+          Canonical, protocols, hasError, true /*allowOnPointerType*/));
       assert(!hasError && "Error when apply protocol qualifier to bound type");
     }
   }

Added: cfe/trunk/test/Modules/odr_hash.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/odr_hash.mm?rev=341013&view=auto
==============================================================================
--- cfe/trunk/test/Modules/odr_hash.mm (added)
+++ cfe/trunk/test/Modules/odr_hash.mm Wed Aug 29 18:57:52 2018
@@ -0,0 +1,74 @@
+// Clear and create directories
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: mkdir %t/cache
+// RUN: mkdir %t/Inputs
+
+// Build first header file
+// RUN: echo "#define FIRST" >> %t/Inputs/first.h
+// RUN: cat %s               >> %t/Inputs/first.h
+
+// Build second header file
+// RUN: echo "#define SECOND" >> %t/Inputs/second.h
+// RUN: cat %s                >> %t/Inputs/second.h
+
+// Test that each header can compile
+// RUN: %clang_cc1 -fsyntax-only -x objective-c++ %t/Inputs/first.h -fblocks -fobjc-arc
+// RUN: %clang_cc1 -fsyntax-only -x objective-c++ %t/Inputs/second.h -fblocks -fobjc-arc
+
+// Build module map file
+// RUN: echo "module FirstModule {"     >> %t/Inputs/module.map
+// RUN: echo "    header \"first.h\""   >> %t/Inputs/module.map
+// RUN: echo "}"                        >> %t/Inputs/module.map
+// RUN: echo "module SecondModule {"    >> %t/Inputs/module.map
+// RUN: echo "    header \"second.h\""  >> %t/Inputs/module.map
+// RUN: echo "}"                        >> %t/Inputs/module.map
+
+// Run test
+// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/cache -x objective-c++ -I%t/Inputs -verify %s -fblocks -fobjc-arc
+
+#if !defined(FIRST) && !defined(SECOND)
+#include "first.h"
+#include "second.h"
+#endif
+
+#if defined(FIRST) || defined(SECOND)
+ at protocol P1
+ at end
+
+ at interface I1
+ at end
+
+ at interface Interface1 <T : I1 *> {
+ at public
+  T<P1> x;
+}
+ at end
+#endif
+
+#if defined(FIRST)
+struct S {
+  Interface1 *I;
+  decltype(I->x) x;
+  int y;
+};
+#elif defined(SECOND)
+struct S {
+  Interface1 *I;
+  decltype(I->x) x;
+  bool y;
+};
+#else
+S s;
+// expected-error at second.h:* {{'S::y' from module 'SecondModule' is not present in definition of 'S' in module 'FirstModule'}}
+// expected-note at first.h:* {{declaration of 'y' does not match}}
+#endif
+
+// Keep macros contained to one file.
+#ifdef FIRST
+#undef FIRST
+#endif
+
+#ifdef SECOND
+#undef SECOND
+#endif




More information about the cfe-commits mailing list