adek05 created this revision.
adek05 added a reviewer: jroelofs.
adek05 added a subscriber: cfe-commits.

Finding original declaration which is suffering from discarding a qualifier is 
somewhat tricky and it doesn't always make sense in all of the contexts that 
DiagnoseAssignmentResult is called.
I haven't figured out yet how to make this change work for ObjC Setters which I 
think is the only place left which should handle this diagnostic.
Current approach is sort of best-effort, but doesn't really guarantee much.

Alternative way to go would be to factor this extra diagnostic out and write it 
in a similar fashion to DiagnoseSelfAssignment and call it in some of the 
contexts when note could be useful.
The problem I see with that, is that it would have issues with handling 
overriden assignment operators or would not work for non built-in types.

http://reviews.llvm.org/D15486

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Sema/Sema.h
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaInit.cpp
  lib/Sema/SemaPseudoObject.cpp
  lib/Sema/SemaStmt.cpp

Index: lib/Sema/SemaStmt.cpp
===================================================================
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -2604,7 +2604,8 @@
     if (ExprRes.isInvalid())
       return StmtError();
     E = ExprRes.get();
-    if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, ETy, E, AA_Passing))
+    if (DiagnoseAssignmentResult(ConvTy, StarLoc, DestTy, nullptr, ETy, E,
+                                 AA_Passing))
       return StmtError();
   }
 
Index: lib/Sema/SemaPseudoObject.cpp
===================================================================
--- lib/Sema/SemaPseudoObject.cpp
+++ lib/Sema/SemaPseudoObject.cpp
@@ -746,7 +746,7 @@
       ExprResult opResult = op;
       Sema::AssignConvertType assignResult
         = S.CheckSingleAssignmentConstraints(paramType, opResult);
-      if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType,
+      if (S.DiagnoseAssignmentResult(assignResult, opcLoc, paramType, nullptr,
                                      op->getType(), opResult.get(),
                                      Sema::AA_Assigning))
         return ExprError();
Index: lib/Sema/SemaInit.cpp
===================================================================
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -6638,11 +6638,11 @@
       CurInit = CurInitExprRes;
 
       bool Complained;
-      if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(),
-                                     Step->Type, SourceType,
-                                     InitialCurInit.get(),
-                                     getAssignmentAction(Entity, true),
-                                     &Complained)) {
+      if (S.DiagnoseAssignmentResult(
+              ConvTy, Kind.getLocation(), Step->Type,
+              Entity.getDecl() ? dyn_cast<VarDecl>(Entity.getDecl()) : nullptr,
+              SourceType, InitialCurInit.get(),
+              getAssignmentAction(Entity, true), &Complained)) {
         PrintInitLocationNote(S, Entity);
         return ExprError();
       } else if (Complained)
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -9612,8 +9612,11 @@
     ConvTy = CheckAssignmentConstraints(Loc, LHSType, RHSType);
   }
 
-  if (DiagnoseAssignmentResult(ConvTy, Loc, LHSType, RHSType,
-                               RHS.get(), AA_Assigning))
+  DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(LHSExpr);
+  if (DiagnoseAssignmentResult(ConvTy, Loc, LHSType,
+                               DeclRef->getDecl() ? DeclRef->getDecl()
+                                                  : nullptr,
+                               RHSType, RHS.get(), AA_Assigning))
     return QualType();
 
   CheckForNullPointerDereference(*this, LHSExpr);
@@ -11864,8 +11867,8 @@
 }
 
 bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
-                                    SourceLocation Loc,
-                                    QualType DstType, QualType SrcType,
+                                    SourceLocation Loc, QualType DstType,
+                                    VarDecl *DstVarDecl, QualType SrcType,
                                     Expr *SrcExpr, AssignmentAction Action,
                                     bool *Complained) {
   if (Complained)
@@ -12051,6 +12054,16 @@
     HandleFunctionTypeMismatch(FDiag, SecondType, FirstType);
 
   Diag(Loc, FDiag);
+
+  // Emit original location of a variable declaration which is on the LHS
+  if (DiagKind == diag::ext_nested_pointer_qualifier_mismatch && DstVarDecl) {
+    SourceRange DstVarDeclSR = DstVarDecl->getSourceRange();
+    PartialDiagnostic Note =
+        PDiag(diag::note_nested_pointer_discarded_qualifier);
+    Note << DstVarDeclSR;
+    Diag(DstVarDeclSR.getBegin(), Note);
+  }
+
   if (DiagKind == diag::warn_incompatible_qualified_id &&
       PDecl && IFace && !IFace->hasDefinition())
       Diag(IFace->getLocation(), diag::not_incomplete_class_and_qualified_id)
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -728,7 +728,8 @@
     ConvTy = CheckSingleAssignmentConstraints(LHSTy, RHS);
     if (RHS.isInvalid())
       return true;
-    if (DiagnoseAssignmentResult(ConvTy, Arg->getLocStart(), LHSTy, RHSTy,
+    if (DiagnoseAssignmentResult(ConvTy, Arg->getLocStart(), LHSTy,
+                                 /* lhs declaration */ nullptr, RHSTy,
                                  RHS.get(), AA_Assigning))
       return true;
   }
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -8352,10 +8352,10 @@
   /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
   /// assignment conversion type specified by ConvTy.  This returns true if the
   /// conversion was invalid or false if the conversion was accepted.
-  bool DiagnoseAssignmentResult(AssignConvertType ConvTy,
-                                SourceLocation Loc,
-                                QualType DstType, QualType SrcType,
-                                Expr *SrcExpr, AssignmentAction Action,
+  bool DiagnoseAssignmentResult(AssignConvertType ConvTy, SourceLocation Loc,
+                                QualType DstType, VarDecl *DstVarDecl,
+                                QualType SrcType, Expr *SrcExpr,
+                                AssignmentAction Action,
                                 bool *Complained = nullptr);
 
   /// IsValueInFlagEnum - Determine if a value is allowed as part of a flag
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -6161,6 +6161,8 @@
   "|%diff{casting $ to type $|casting between types}0,1}2"
   " discards qualifiers">,
   InGroup<IncompatiblePointerTypesDiscardsQualifiers>;
+def note_nested_pointer_discarded_qualifier : Note<
+  "nested pointer type with discarded 'const' qualifier">;
 def ext_nested_pointer_qualifier_mismatch : ExtWarn<
   "%select{%diff{assigning to $ from $|assigning to different types}0,1"
   "|%diff{passing $ to parameter of type $|"
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to