[PATCH] D90448: [clang] Add type check for explicit instantiation of static data members

Chuyang Chen via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Nov 8 20:49:15 PST 2020


nomanous updated this revision to Diff 303749.
nomanous added a comment.

Some more format fixes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90448/new/

https://reviews.llvm.org/D90448

Files:
  clang/include/clang/AST/ASTContext.h
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaTemplate.cpp


Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -10027,6 +10027,7 @@
 
     VarDecl *Prev = Previous.getAsSingle<VarDecl>();
     VarTemplateDecl *PrevTemplate = Previous.getAsSingle<VarTemplateDecl>();
+    bool IsStaticDataMemberInstantiation = false;
 
     if (!PrevTemplate) {
       if (!Prev || !Prev->isStaticDataMember()) {
@@ -10048,6 +10049,8 @@
         // FIXME: Can we provide a note showing where this was declared?
         return true;
       }
+
+      IsStaticDataMemberInstantiation = true;
     } else {
       // Explicitly instantiate a variable template.
 
@@ -10140,6 +10143,21 @@
       return true;
     }
 
+    // Check the static member's type given in the explicit instantiation
+    // definition against the one in the class template. This won't happen in
+    // explicit instantiation declaration because the instantiated code won't
+    // be generated in that case.
+    if (IsStaticDataMemberInstantiation &&
+        TSK == TSK_ExplicitInstantiationDefinition && Prev &&
+        !Context.hasSameTypeIgnoreLifetime(Prev->getType(), R)) {
+      Diag(T->getTypeLoc().getBeginLoc(),
+           diag::err_invalid_template_static_data_member_spec_type)
+          << Prev << R << Prev->getType();
+      Diag(Prev->getLocation(), diag::note_template_static_data_member_def_here)
+          << Prev;
+      return true;
+    }
+
     // FIXME: Create an ExplicitInstantiation node?
     return (Decl*) nullptr;
   }
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5056,6 +5056,8 @@
   "of %select{explicit instantiation|explicit specialization|"
   "partial specialization|redeclaration}0 of %1 does not match"
   " expected type %3">;
+def err_invalid_template_static_data_member_spec_type : Error<"type %1 "
+  "of explicit instantiation of %q0 does not match expected type %2">;
 def err_mismatched_exception_spec_explicit_instantiation : Error<
   "exception specification in explicit instantiation does not match "
   "instantiated one">;
Index: clang/include/clang/AST/ASTContext.h
===================================================================
--- clang/include/clang/AST/ASTContext.h
+++ clang/include/clang/AST/ASTContext.h
@@ -2343,6 +2343,20 @@
   bool hasSameType(QualType T1, QualType T2) const {
     return getCanonicalType(T1) == getCanonicalType(T2);
   }
+
+  /// Determine whether the given types \p T1 and \p T2 are equivalent with
+  /// lifetime qualifiers ignored. We want this because with option -fobjc-arc,
+  /// the compiler automatically adds Objective C lifetime qualifiers for
+  /// static data members. Sometimes, this will make two types not equal while
+  /// they should be.
+  bool hasSameTypeIgnoreLifetime(QualType T1, QualType T2) const {
+    SplitQualType ST1 = getCanonicalType(T1).split();
+    SplitQualType ST2 = getCanonicalType(T2).split();
+    ST1.Quals.removeObjCLifetime();
+    ST2.Quals.removeObjCLifetime();
+    return ST1 == ST2;
+  }
+
   bool hasSameType(const Type *T1, const Type *T2) const {
     return getCanonicalType(T1) == getCanonicalType(T2);
   }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D90448.303749.patch
Type: text/x-patch
Size: 3377 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201109/c6a2319e/attachment.bin>


More information about the cfe-commits mailing list