r365382 - [Sema] Resolve placeholder types before type deduction to silence

Akira Hatanaka via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 8 13:04:40 PDT 2019


Author: ahatanak
Date: Mon Jul  8 13:04:39 2019
New Revision: 365382

URL: http://llvm.org/viewvc/llvm-project?rev=365382&view=rev
Log:
[Sema] Resolve placeholder types before type deduction to silence
spurious `-Warc-repeated-use-of-weak` warnings

The spurious -Warc-repeated-use-of-weak warnings are issued when an
initializer expression uses a weak ObjC pointer.

My first attempt to silence the warnings (r350917) caused clang to
reject code that is legal in C++17. The patch is based on the feedback I
received from Richard when the patch was reverted.

http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20190422/268945.html
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20190422/268943.html

Differential Revision: https://reviews.llvm.org/D62645

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/Basic/Attr.td
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/SemaObjC/arc-repeated-weak.mm

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=365382&r1=365381&r2=365382&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Mon Jul  8 13:04:39 2019
@@ -490,6 +490,15 @@ public:
     return false;
   }
 
+  /// Returns whether this expression has a placeholder type that isn't
+  /// Overload.
+  bool hasNonOverloadPlaceholderType() const {
+    if (auto *PlaceholderType = getType()->getAsPlaceholderType())
+      if (PlaceholderType->isNonOverloadPlaceholderType())
+        return true;
+    return false;
+  }
+
   /// isKnownToHaveBooleanValue - Return true if this is an integer expression
   /// that is known to return 0 or 1.  This happens for _Bool/bool expressions
   /// but also int expressions which are produced by things like comparisons in

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=365382&r1=365381&r2=365382&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Mon Jul  8 13:04:39 2019
@@ -1844,6 +1844,16 @@ def ObjCBoxable : Attr {
   let Documentation = [ObjCBoxableDocs];
 }
 
+
+// This is used to indicate that the type of the annotated variable's
+// initializer was changed from UnknownAny to 'id'.
+def ObjCDefaultedAnyToId : Attr {
+  // This attribute has no spellings as it is only ever created implicitly.
+  let Spellings = [];
+  let Subjects = SubjectList<[Var]>;
+  let Documentation = [Undocumented];
+}
+
 def OptimizeNone : InheritableAttr {
   let Spellings = [Clang<"optnone">];
   let Subjects = SubjectList<[Function, ObjCMethod]>;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=365382&r1=365381&r2=365382&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Jul  8 13:04:39 2019
@@ -10985,18 +10985,6 @@ QualType Sema::deduceVarTypeFromInitiali
     return QualType();
   }
 
-  // Expressions default to 'id' when we're in a debugger.
-  bool DefaultedAnyToId = false;
-  if (getLangOpts().DebuggerCastResultToId &&
-      Init->getType() == Context.UnknownAnyTy && !IsInitCapture) {
-    ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType());
-    if (Result.isInvalid()) {
-      return QualType();
-    }
-    Init = Result.get();
-    DefaultedAnyToId = true;
-  }
-
   // C++ [dcl.decomp]p1:
   //   If the assignment-expression [...] has array type A and no ref-qualifier
   //   is present, e has type cv A
@@ -11030,6 +11018,7 @@ QualType Sema::deduceVarTypeFromInitiali
   // checks.
   // We only want to warn outside of template instantiations, though:
   // inside a template, the 'id' could have come from a parameter.
+  bool DefaultedAnyToId = VDecl && VDecl->hasAttr<ObjCDefaultedAnyToIdAttr>();
   if (!inTemplateInstantiation() && !DefaultedAnyToId && !IsInitCapture &&
       !DeducedType.isNull() && DeducedType->isObjCIdType()) {
     SourceLocation Loc = TSI->getTypeLoc().getBeginLoc();
@@ -11108,6 +11097,27 @@ void Sema::AddInitializerToDecl(Decl *Re
     }
     Init = Res.get();
 
+    // Expressions default to 'id' when we're in a debugger
+    // and we are assigning it to a variable of Objective-C pointer type.
+    if (getLangOpts().DebuggerCastResultToId &&
+        Init->getType() == Context.UnknownAnyTy) {
+      ExprResult Result = forceUnknownAnyToType(Init, Context.getObjCIdType());
+      if (Result.isInvalid()) {
+        VDecl->setInvalidDecl();
+        return;
+      }
+      Init = Result.get();
+      VDecl->addAttr(ObjCDefaultedAnyToIdAttr::CreateImplicit(Context));
+    } else if (!Init->getType().isNull() &&
+               Init->hasNonOverloadPlaceholderType()) {
+      Res = CheckPlaceholderExpr(Init).get();
+      if (!Res.isUsable()) {
+        VDecl->setInvalidDecl();
+        return;
+      }
+      Init = Res.get();
+    }
+
     if (DeduceVariableDeclarationType(VDecl, DirectInit, Init))
       return;
   }

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=365382&r1=365381&r2=365382&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jul  8 13:04:39 2019
@@ -6678,6 +6678,14 @@ Sema::MaybeConvertParenListExprToParenEx
 ExprResult Sema::ActOnParenListExpr(SourceLocation L,
                                     SourceLocation R,
                                     MultiExprArg Val) {
+  for (size_t I = 0, E = Val.size(); I != E; ++I)
+    if (Val[I]->hasNonOverloadPlaceholderType()) {
+      ExprResult Result = CheckPlaceholderExpr(Val[I]);
+      if (!Result.isUsable())
+        return ExprError();
+      Val[I] = Result.get();
+    }
+
   return ParenListExpr::Create(Context, L, Val, R);
 }
 

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=365382&r1=365381&r2=365382&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Mon Jul  8 13:04:39 2019
@@ -1793,6 +1793,14 @@ Sema::BuildCXXNew(SourceRange Range, boo
     NumInits = List->getNumExprs();
   }
 
+  for (unsigned I = 0, E = NumInits; I != E; ++I)
+    if (Inits[I]->hasNonOverloadPlaceholderType()) {
+      ExprResult Result = CheckPlaceholderExpr(Inits[I]);
+      if (!Result.isUsable())
+        return ExprError();
+      Inits[I] = Result.get();
+    }
+
   // C++11 [expr.new]p15:
   //   A new-expression that creates an object of type T initializes that
   //   object as follows:

Modified: cfe/trunk/test/SemaObjC/arc-repeated-weak.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/arc-repeated-weak.mm?rev=365382&r1=365381&r2=365382&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/arc-repeated-weak.mm (original)
+++ cfe/trunk/test/SemaObjC/arc-repeated-weak.mm Mon Jul  8 13:04:39 2019
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
-// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++11 -Warc-repeated-use-of-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-arc -fblocks -Wno-objc-root-class -std=c++14 -Warc-repeated-use-of-weak -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-runtime-has-weak -fobjc-weak -fblocks -Wno-objc-root-class -std=c++14 -Warc-repeated-use-of-weak -verify %s
 
 @interface Test {
 @public
@@ -467,6 +467,18 @@ void foo() {
   __typeof__(NSBundle2.foo2.weakProp) t5;
 }
 
+void testAuto() {
+  auto __weak wp = NSBundle2.foo2.weakProp;
+}
+
+void testLambdaCaptureInit() {
+  [capture(NSBundle2.foo2.weakProp)] {} ();
+}
+
+void testAutoNew() {
+  auto p = new auto(NSBundle2.foo2.weakProp);
+}
+
 // This used to crash in the constructor of WeakObjectProfileTy when a
 // DeclRefExpr was passed that didn't reference a VarDecl.
 




More information about the cfe-commits mailing list