[PATCH] D67549: [IntrinsicEmitter] Add overloaded types for SVE intrinsics (Subdivide2 & Subdivide4)

2019-09-20 Thread Sander de Smalen via Phabricator via cfe-commits
sdesmalen accepted this revision.
sdesmalen added a comment.
This revision is now accepted and ready to land.

Thanks, LGTM!


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

https://reviews.llvm.org/D67549



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D65433: [clangd] DefineInline action availability checks

2019-09-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein added a comment.

mostly good to me, a few more comments.




Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:183
+/// a.h:
+///   void foo() { return ; }
+///

kadircet wrote:
> hokein wrote:
> > now we get a potential ODR violation in this example, maybe choose a 
> > different example?
> You are right, but we cannot get away from it by changing the example. Adding 
> an "inline " instead, and I believe that's what we should do if we are moving 
> a function definition to a header.
I think not all cases will need inline, e.g. class method, or function 
template(?).  Fix these problems is out-scope of the tweak (there is a 
clang-tidy check handling this case), and probably add complexity to the 
implementation. I'm leaning on not fixing it.

Maybe a better example is class method?



Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:156
+// rather then declaration of specialization.
+const FunctionDecl *choseCanonical(const FunctionDecl *FD) {
+  if (FD->isFunctionTemplateSpecialization()) {

maybe name it `findTarget`? I think the function is used to find a potential 
target decl which the definition will be moved to,  `Canonical` doesn't provide 
much information here.



Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:160
+// target we want to inline into. Instead we use the previous declaration.
+return FD->getPreviousDecl();
+  }

We may get a nullptr if FD is the first declaration, I think we need to handle 
the nullptr case, otherwise the check will crash.



Comment at: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp:185
+  Intent intent() const override { return Intent::Refactor; }
+  std::string title() const override { return "Inline function definition"; }
+  bool hidden() const override { return true; }

I'm not sure `Inline function definition` is a widely-known refactoring term, I 
think "Move function definition to declaration" is probably easier for normal 
C++ developers to understand?



Comment at: clang-tools-extra/clangd/unittests/TweakTests.cpp:712
+  bar();
+})cpp");
+

I think we missing a basic test where a declaration is in the header and it can 
be moved?

Header = "void foo();"
Main = "void f^oo() { // no dependency code }"


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D65433



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67748: [clangd] Add a helper for extracting nonlocal decls in a FunctionDecl

2019-09-20 Thread Haojian Wu via Phabricator via cfe-commits
hokein added a comment.

I think the helper is only used by the defineInline tweak? not sure XRef.h is 
the best place for putting these helpers.
Will we have more helpers in the future? If so, we may put them all in a new 
file.




Comment at: clang-tools-extra/clangd/unittests/XRefsTests.cpp:2258
+sourceLocationInMainFile(AST.getSourceManager(), File.point());
+ASSERT_TRUE(bool(SL));
+

nit: use `SourceLocation SL = cantfail( 
sourceLocationInMainFile(AST.getSourceManager(), File.point());` .


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67748



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67501: [clang-tidy] Fix relative path in header-filter.

2019-09-20 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr added inline comments.



Comment at: clang-tools-extra/test/clang-tidy/file-filter.cpp:60
+// CHECK4-QUIET: header.h:1:12: warning: single-argument constructors must be 
marked explicit
+// CHECK5: header.h:3:12: warning: single-argument constructors must be marked 
explicit
+// CHECK5-QUIET: header.h:3:12: warning: single-argument constructors must be 
marked explicit

Could you rename `header.h` files to `header_a.h`, `header_b.h` etc. to make it 
obvious in CHECK lines where the messages are coming from?


Repository:
  rCTE Clang Tools Extra

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

https://reviews.llvm.org/D67501



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67501: [clang-tidy] Fix relative path in header-filter.

2019-09-20 Thread MyDeveloperDay via Phabricator via cfe-commits
MyDeveloperDay added inline comments.



Comment at: clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp:555
+  StringRef FileName = File->tryGetRealPathName();
+  if (FileName.empty()) {
+FileName = File->getName();

elide the {}


Repository:
  rCTE Clang Tools Extra

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

https://reviews.llvm.org/D67501



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67549: [IntrinsicEmitter] Add overloaded types for SVE intrinsics (Subdivide2 & Subdivide4)

2019-09-20 Thread Kerry McLaughlin via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL372380: [IntrinsicEmitter] Add overloaded types for SVE 
intrinsics (Subdivide2 &… (authored by kmclaughlin, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D67549?vs=220886&id=220988#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D67549

Files:
  llvm/trunk/include/llvm/IR/DerivedTypes.h
  llvm/trunk/include/llvm/IR/Intrinsics.h
  llvm/trunk/include/llvm/IR/Intrinsics.td
  llvm/trunk/lib/IR/Function.cpp
  llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp

Index: llvm/trunk/lib/IR/Function.cpp
===
--- llvm/trunk/lib/IR/Function.cpp
+++ llvm/trunk/lib/IR/Function.cpp
@@ -703,7 +703,9 @@
   IIT_STRUCT8 = 40,
   IIT_F128 = 41,
   IIT_VEC_ELEMENT = 42,
-  IIT_SCALABLE_VEC = 43
+  IIT_SCALABLE_VEC = 43,
+  IIT_SUBDIVIDE2_ARG = 44,
+  IIT_SUBDIVIDE4_ARG = 45
 };
 
 static void DecodeIITType(unsigned &NextElt, ArrayRef Infos,
@@ -868,6 +870,18 @@
   DecodeIITType(NextElt, Infos, OutputTable);
 return;
   }
+  case IIT_SUBDIVIDE2_ARG: {
+unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+OutputTable.push_back(IITDescriptor::get(IITDescriptor::Subdivide2Argument,
+ ArgInfo));
+return;
+  }
+  case IIT_SUBDIVIDE4_ARG: {
+unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
+OutputTable.push_back(IITDescriptor::get(IITDescriptor::Subdivide4Argument,
+ ArgInfo));
+return;
+  }
   case IIT_VEC_ELEMENT: {
 unsigned ArgInfo = (NextElt == Infos.size() ? 0 : Infos[NextElt++]);
 OutputTable.push_back(IITDescriptor::get(IITDescriptor::VecElementArgument,
@@ -970,6 +984,14 @@
 assert(ITy->getBitWidth() % 2 == 0);
 return IntegerType::get(Context, ITy->getBitWidth() / 2);
   }
+  case IITDescriptor::Subdivide2Argument:
+  case IITDescriptor::Subdivide4Argument: {
+Type *Ty = Tys[D.getArgumentNumber()];
+VectorType *VTy = dyn_cast(Ty);
+assert(VTy && "Expected an argument of Vector Type");
+int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
+return VectorType::getSubdividedVectorType(VTy, SubDivs);
+  }
   case IITDescriptor::HalfVecArgument:
 return VectorType::getHalfElementsVectorType(cast(
   Tys[D.getArgumentNumber()]));
@@ -1269,6 +1291,20 @@
   auto *ReferenceType = dyn_cast(ArgTys[D.getArgumentNumber()]);
   return !ReferenceType || Ty != ReferenceType->getElementType();
 }
+case IITDescriptor::Subdivide2Argument:
+case IITDescriptor::Subdivide4Argument: {
+  // If this is a forward reference, defer the check for later.
+  if (D.getArgumentNumber() >= ArgTys.size())
+return IsDeferredCheck || DeferCheck(Ty);
+
+  Type *NewTy = ArgTys[D.getArgumentNumber()];
+  if (auto *VTy = dyn_cast(NewTy)) {
+int SubDivs = D.Kind == IITDescriptor::Subdivide2Argument ? 1 : 2;
+NewTy = VectorType::getSubdividedVectorType(VTy, SubDivs);
+return Ty != NewTy;
+  }
+  return true;
+}
 case IITDescriptor::ScalableVecArgument: {
   VectorType *VTy = dyn_cast(Ty);
   if (!VTy || !VTy->isScalable())
Index: llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
===
--- llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
+++ llvm/trunk/utils/TableGen/IntrinsicEmitter.cpp
@@ -221,7 +221,9 @@
   IIT_STRUCT8 = 40,
   IIT_F128 = 41,
   IIT_VEC_ELEMENT = 42,
-  IIT_SCALABLE_VEC = 43
+  IIT_SCALABLE_VEC = 43,
+  IIT_SUBDIVIDE2_ARG = 44,
+  IIT_SUBDIVIDE4_ARG = 45
 };
 
 static void EncodeFixedValueType(MVT::SimpleValueType VT,
@@ -293,6 +295,10 @@
   Sig.push_back(IIT_PTR_TO_ELT);
 else if (R->isSubClassOf("LLVMVectorElementType"))
   Sig.push_back(IIT_VEC_ELEMENT);
+else if (R->isSubClassOf("LLVMSubdivide2VectorType"))
+  Sig.push_back(IIT_SUBDIVIDE2_ARG);
+else if (R->isSubClassOf("LLVMSubdivide4VectorType"))
+  Sig.push_back(IIT_SUBDIVIDE4_ARG);
 else
   Sig.push_back(IIT_ARG);
 return Sig.push_back((Number << 3) | 7 /*IITDescriptor::AK_MatchType*/);
Index: llvm/trunk/include/llvm/IR/DerivedTypes.h
===
--- llvm/trunk/include/llvm/IR/DerivedTypes.h
+++ llvm/trunk/include/llvm/IR/DerivedTypes.h
@@ -475,16 +475,42 @@
 return VectorType::get(EltTy, VTy->getElementCount());
   }
 
-  /// This static method is like getInteger except that the element types are
-  /// half as wide as the elements in the input type.
+  // This static method gets a VectorType with the same number of elements as
+  // the input type, and the element type is an integer or float type which
+  // is half as wide as the elements in the i

[PATCH] D67501: [clang-tidy] Fix relative path in header-filter.

2019-09-20 Thread Yubo Xie via Phabricator via cfe-commits
xyb updated this revision to Diff 220997.
xyb marked 2 inline comments as done.
xyb added a comment.

Updated


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

https://reviews.llvm.org/D67501

Files:
  clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
  clang-tools-extra/test/clang-tidy/Inputs/file-filter/subfolder_a/header_a.h
  clang-tools-extra/test/clang-tidy/Inputs/file-filter/subfolder_b/header_b.h
  clang-tools-extra/test/clang-tidy/Inputs/file-filter/subfolder_c/header_c.h
  clang-tools-extra/test/clang-tidy/file-filter.cpp

Index: clang-tools-extra/test/clang-tidy/file-filter.cpp
===
--- clang-tools-extra/test/clang-tidy/file-filter.cpp
+++ clang-tools-extra/test/clang-tidy/file-filter.cpp
@@ -9,6 +9,12 @@
 //   file-filter\header*.h due to code order between '/' and '\\'.
 // RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4 %s
 // RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers -quiet %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4-QUIET %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_a' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_a' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK5-QUIET %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_b' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_b' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK6-QUIET %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_c' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK7 %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_c' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK7-QUIET %s
 
 #include "header1.h"
 // CHECK-NOT: warning:
@@ -19,6 +25,12 @@
 // CHECK3-QUIET-NOT: warning:
 // CHECK4: header1.h:1:12: warning: single-argument constructors
 // CHECK4-QUIET: header1.h:1:12: warning: single-argument constructors
+// CHECK5-NOT: warning:
+// CHECK5-QUIET-NOT: warning:
+// CHECK6-NOT: warning:
+// CHECK6-QUIET-NOT: warning:
+// CHECK7-NOT: warning:
+// CHECK7-QUIET-NOT: warning:
 
 #include "header2.h"
 // CHECK-NOT: warning:
@@ -29,6 +41,44 @@
 // CHECK3-QUIET: header2.h:1:12: warning: single-argument constructors
 // CHECK4: header2.h:1:12: warning: single-argument constructors
 // CHECK4-QUIET: header2.h:1:12: warning: single-argument constructors
+// CHECK5-NOT: warning:
+// CHECK5-QUIET-NOT: warning:
+// CHECK6-NOT: warning:
+// CHECK6-QUIET-NOT: warning:
+// CHECK7-NOT: warning:
+// CHECK7-QUIET-NOT: warning:
+
+#include "subfolder_a/header_a.h"
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+// CHECK2: header_b.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK2-QUIET: header_b.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK3-NOT: warning:
+// CHECK3-QUIET-NOT: warning:
+// CHECK4: header_b.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK4-QUIET: header_b.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK5: header_a.h:3:12: warning: single-argument constructors must be marked explicit
+// CHECK5-QUIET: header_a.h:3:12: warning: single-argument constructors must be marked explicit
+// CHECK6: header_b.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK6-QUIET: header_b.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK7-NOT: warning:
+// CHECK7-QUIET-NOT: warning:
+
+#include "subfolder_c/header_c.h"
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+// CHECK2: header_c.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK2-QUIET: header_c.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK3-NOT: warning:
+// CHECK3-QUIET-NOT: warning:
+// CHECK4: header_c.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK4-QUIET: header_c.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK5-NOT: warning:
+// CHECK5-QUIET-NOT: warning:
+// CHECK6-NOT: warning:
+// CHE

[PATCH] D67825: [AST] Extrat Decl::printQualifier helper from Decl::printQualifiedName.

2019-09-20 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov created this revision.
ilya-biryukov added a reviewer: kadircet.
Herald added a subscriber: usaxena95.
Herald added a project: clang.

To be used in clangd, e.g. in D66647 .


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D67825

Files:
  clang/include/clang/AST/Decl.h
  clang/lib/AST/Decl.cpp


Index: clang/lib/AST/Decl.cpp
===
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -1558,6 +1558,18 @@
 
 void NamedDecl::printQualifiedName(raw_ostream &OS,
const PrintingPolicy &P) const {
+  printQualifier(OS, P);
+  if (getDeclName() || isa(this))
+OS << *this;
+  else
+OS << "(anonymous)";
+}
+
+void NamedDecl::printQualifier(raw_ostream &OS) const {
+  printQualifier(OS, getASTContext().getPrintingPolicy());
+}
+
+void NamedDecl::printQualifier(raw_ostream &OS, const PrintingPolicy &P) const 
{
   const DeclContext *Ctx = getDeclContext();
 
   // For ObjC methods and properties, look through categories and use the
@@ -1571,10 +1583,8 @@
 Ctx = ID;
   }
 
-  if (Ctx->isFunctionOrMethod()) {
-printName(OS);
+  if (Ctx->isFunctionOrMethod())
 return;
-  }
 
   using ContextsTy = SmallVector;
   ContextsTy Contexts;
@@ -1644,11 +1654,6 @@
 }
 OS << "::";
   }
-
-  if (getDeclName() || isa(this))
-OS << *this;
-  else
-OS << "(anonymous)";
 }
 
 void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
Index: clang/include/clang/AST/Decl.h
===
--- clang/include/clang/AST/Decl.h
+++ clang/include/clang/AST/Decl.h
@@ -310,6 +310,13 @@
   void printQualifiedName(raw_ostream &OS) const;
   void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
 
+  /// Returns only qualifier from printQualifiedName, including the :: at the
+  /// end. E.g.
+  ///when `printQualifiedName(D) == "A::B::i`,
+  ///this function returns "A::B::".
+  void printQualifier(raw_ostream &OS) const;
+  void printQualifier(raw_ostream &OS, const PrintingPolicy &Policy) const;
+
   // FIXME: Remove string version.
   std::string getQualifiedNameAsString() const;
 


Index: clang/lib/AST/Decl.cpp
===
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -1558,6 +1558,18 @@
 
 void NamedDecl::printQualifiedName(raw_ostream &OS,
const PrintingPolicy &P) const {
+  printQualifier(OS, P);
+  if (getDeclName() || isa(this))
+OS << *this;
+  else
+OS << "(anonymous)";
+}
+
+void NamedDecl::printQualifier(raw_ostream &OS) const {
+  printQualifier(OS, getASTContext().getPrintingPolicy());
+}
+
+void NamedDecl::printQualifier(raw_ostream &OS, const PrintingPolicy &P) const {
   const DeclContext *Ctx = getDeclContext();
 
   // For ObjC methods and properties, look through categories and use the
@@ -1571,10 +1583,8 @@
 Ctx = ID;
   }
 
-  if (Ctx->isFunctionOrMethod()) {
-printName(OS);
+  if (Ctx->isFunctionOrMethod())
 return;
-  }
 
   using ContextsTy = SmallVector;
   ContextsTy Contexts;
@@ -1644,11 +1654,6 @@
 }
 OS << "::";
   }
-
-  if (getDeclName() || isa(this))
-OS << *this;
-  else
-OS << "(anonymous)";
 }
 
 void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
Index: clang/include/clang/AST/Decl.h
===
--- clang/include/clang/AST/Decl.h
+++ clang/include/clang/AST/Decl.h
@@ -310,6 +310,13 @@
   void printQualifiedName(raw_ostream &OS) const;
   void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
 
+  /// Returns only qualifier from printQualifiedName, including the :: at the
+  /// end. E.g.
+  ///when `printQualifiedName(D) == "A::B::i`,
+  ///this function returns "A::B::".
+  void printQualifier(raw_ostream &OS) const;
+  void printQualifier(raw_ostream &OS, const PrintingPolicy &Policy) const;
+
   // FIXME: Remove string version.
   std::string getQualifiedNameAsString() const;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67826: [clangd] A helper to find explicit references and their names

2019-09-20 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov created this revision.
ilya-biryukov added a reviewer: kadircet.
Herald added subscribers: usaxena95, arphaman, jkorous, MaskRay.
Herald added a project: clang.

Allows to simplify pending code tweaks:

- the upcoming DefineInline tweak (D66647 )
- remove using declaration (D56612 )
- qualify name under cursor (D56610 )

Another potential future application is simplifying semantic highlighting.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D67826

Files:
  clang-tools-extra/clangd/FindTarget.cpp
  clang-tools-extra/clangd/FindTarget.h

Index: clang-tools-extra/clangd/FindTarget.h
===
--- clang-tools-extra/clangd/FindTarget.h
+++ clang-tools-extra/clangd/FindTarget.h
@@ -20,8 +20,13 @@
 //===--===//
 
 #include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/Stmt.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
 
 #include 
 
@@ -69,6 +74,47 @@
 llvm::SmallVector
 targetDecl(const ast_type_traits::DynTypedNode &, DeclRelationSet Mask);
 
+/// Information about a reference written in the source code, independent of the
+/// actual AST node that this reference lives in.
+/// Useful for tools that are source-aware, e.g. refactorings.
+struct ReferenceLoc {
+  /// Contains qualifier written in the code, if any, e.g. 'ns::' for 'ns::foo'.
+  NestedNameSpecifierLoc Qualifier;
+  /// Start location of the last name part, i.e. 'foo' in 'ns::foo'.
+  SourceLocation NameLoc;
+  // FIXME: add info about template arguments.
+  /// A list of targets referenced by this name. Normally this has a single
+  /// element, but multiple is also possible, e.g. in case of using declarations
+  /// or unresolved overloaded functions.
+  /// For dependent and unresolved references, Targets can also be empty.
+  llvm::SmallVector Targets;
+  /// If reference comes from a MemberExpr, the LHS of the reference, e.g. 'obj'
+  /// in 'obj.foo'.
+  const Expr* MemberExprBase = nullptr;
+};
+
+/// Obtain information about a reference in \p N, if any. Note that any of the
+/// fields in the returned structure can be empty, but not all of them, e.g.
+///   - for implicitly generated nodes (e.g. MemberExpr from range-based-for),
+/// source location information may be missing,
+///   - for dependent code, targets may be empty.
+///
+/// (!) For the purposes of this function declarations are not considered to be
+/// references. However, declarations can have:wa references inside them,
+/// e.g. 'namespace foo = std' references namespace 'std' and this function
+/// will return the corresponding reference.
+llvm::Optional
+explicitReference(ast_type_traits::DynTypedNode N);
+
+/// Recursively traverse \p S and report all references explicitly written in
+/// the code. The main use-case is refactorings that need to process all
+/// references in some subrange of the file and apply simple edits, e.g. add
+/// qualifiers.
+/// FIXME: currently this does not report references to overloaded operators.
+/// FIXME: extend to report location information about declaration names too.
+void findExplicitReferences(Stmt *S,
+llvm::function_ref Out);
+
 /// Similar to targetDecl(), however instead of applying a filter, all possible
 /// decls are returned along with their DeclRelationSets.
 /// This is suitable for indexing, where everything is recorded and filtering
Index: clang-tools-extra/clangd/FindTarget.cpp
===
--- clang-tools-extra/clangd/FindTarget.cpp
+++ clang-tools-extra/clangd/FindTarget.cpp
@@ -10,22 +10,31 @@
 #include "AST.h"
 #include "Logger.h"
 #include "clang/AST/ASTTypeTraits.h"
+#include "clang/AST/Decl.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclVisitor.h"
 #include "clang/AST/DeclarationName.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/ExprObjC.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/StmtVisitor.h"
 #include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
 #include "clang/AST/TypeLocVisitor.h"
 #include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
+#include 
 
 namespace clang {
 namespace clangd {
 namespace {
+using ast_type_traits::DynTypedNode;
 
 LLVM_ATTRIBUTE_UNUSED std::string
 nodeToString(const ast_type_traits::DynTypedNode &N) {
@@ -348,12 +357,246 @@
 llvm::SmallVector
 targetDecl(const ast_

[PATCH] D67827: [clangd] Simplify name qualification in DefineInline

2019-09-20 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added a comment.

It's probably better to land this as part of D66647 
, posting this here for demonstrative purposes


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67827



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67827: [clangd] Simplify name qualification in DefineInline

2019-09-20 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov created this revision.
Herald added subscribers: usaxena95, arphaman, jkorous, MaskRay.
Herald added a project: clang.
ilya-biryukov added parent revisions: D67826: [clangd] A helper to find 
explicit references and their names, D67825: [AST] Extrat Decl::printQualifier 
helper from Decl::printQualifiedName..
ilya-biryukov added a parent revision: D66647: [clangd] DefineInline action 
apply logic with fully qualified names.

By using new helpers from FindTarget.h


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D67827

Files:
  clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp
  clang-tools-extra/clangd/unittests/TweakTests.cpp

Index: clang-tools-extra/clangd/unittests/TweakTests.cpp
===
--- clang-tools-extra/clangd/unittests/TweakTests.cpp
+++ clang-tools-extra/clangd/unittests/TweakTests.cpp
@@ -993,8 +993,8 @@
 
   void foo()/*Comment -_-*/  {
 using namespace a;
-a::bar >.bar();
-a::aux >();
+a::bar>.bar();
+a::aux>();
   }
 
   
@@ -1067,7 +1067,6 @@
   template 
   void f^oo() {
 Bar B;
-// FIXME: This should be a::Bar >
 Bar> q;
   }
   )cpp",
@@ -1080,8 +1079,7 @@
   template 
   void foo()/*Comment -_-*/  {
 a::Bar B;
-// FIXME: This should be a::Bar >
-a::Bar > q;
+a::Bar> q;
   }
 
   
@@ -1218,7 +1216,7 @@
   void foo()/*Comment -_-*/  {
 a::Bar B;
 a::b::Foo foo;
-a::Bar >::Baz > q;
+a::Bar>::Baz> q;
   }
 
   
@@ -1287,7 +1285,7 @@
 a::Bar B;
 B.foo();
 a::bar();
-a::Bar >::bar();
+a::Bar>::bar();
 a::Bar::bar();
 B.x = a::Bar::y;
 a::Bar::y = 3;
Index: clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp
===
--- clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp
+++ clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp
@@ -48,6 +48,7 @@
 #include "llvm/Support/Error.h"
 #include "llvm/Support/Signals.h"
 #include "llvm/Support/raw_ostream.h"
+#include "FindTarget.h"
 #include 
 #include 
 #include 
@@ -93,251 +94,6 @@
   return nullptr;
 }
 
-// There are three types of spellings that needs to be qualified in a function
-// body:
-// - Types:   Foo -> ns::Foo
-// - DeclRefExpr: ns2::foo()  -> ns1::ns2::foo();
-// - UsingDecls:
-//using ns2::foo  -> using ns1::ns2::foo
-//using namespace ns2 -> using namespace ns1::ns2
-//using ns3 = ns2 -> using ns3 = ns1::ns2
-//
-// Goes over all DeclRefExprs, TypeLocs, and Using{,Directive}Decls inside a
-// function body to generate replacements that will fully qualify those. So that
-// body can be moved into an arbitrary file.
-// We perform the qualification by qualyfying the last type/decl in a
-// (un)qualified name. e.g:
-//namespace a { namespace b { class Bar{}; void foo(); } }
-//b::Bar x; -> a::b::Bar x;
-//foo(); -> a::b::foo();
-// Currently there is no way to know whether a given TypeLoc is the last one or
-// not, therefore we generate replacements for all the TypeLocs we see in a
-// given name and pick only the longest one.
-// FIXME: Instead of fully qualyfying we should try deducing visible scopes at
-// target location and generate minimal edits.
-class QualifyingVisitor : public RecursiveASTVisitor {
-public:
-  QualifyingVisitor(const FunctionDecl *FD)
-  : LangOpts(FD->getASTContext().getLangOpts()),
-SM(FD->getASTContext().getSourceManager()),
-BodyBegin(SM.getFileOffset(FD->getBody()->getBeginLoc())) {
-TraverseStmt(FD->getBody());
-  }
-
-  // We override traversals for DeclRefExprs and TypeLocs to generate an edit
-  // only for the last Type/Decl in a written name. Also it enables us to catch
-  // current range of the name as written, since the last Type/Decl doesn't
-  // contain that information.
-  bool TraverseDeclRefExpr(DeclRefExpr *DRE) {
-maybeUpdateCurrentRange(DRE->getSourceRange());
-return RecursiveASTVisitor::TraverseDeclRefExpr(DRE);
-  }
-
-  bool TraverseTypeLoc(TypeLoc TL) {
-maybeUpdateCurrentRange(TL.getSourceRange());
-return RecursiveASTVisitor::TraverseTypeLoc(TL);
-  }
-
-  // Generates a replacement that will qualify templated name and arguments.
-  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TSTL) {
-std::string Qualified;
-llvm::raw_string_ostream OS(Qualified);
-
-QualType Ty = TSTL.getType();
-if (Ty->isDependentType()) {
-  // We don't have a decl if type is dependent, use the TemplateDecl
-  // instead.
-  const TemplateDecl *TD =
-  TSTL.getTypePtr()->getTemplateName().getAsTemplateDecl();
-
-  TD->printQualifiedName(OS);
-  // FIXME: For some reason this prints types as written in source code,
-  // instead of fully qualified version,
-  //  i.e: a::Bar> instead of a::Bar>
-  printTemplateArgumentList(OS, TSTL.getTypePtr()->templa

[PATCH] D67825: [AST] Extract Decl::printQualifier helper from Decl::printQualifiedName

2019-09-20 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a reviewer: aaron.ballman.
aaron.ballman added inline comments.



Comment at: clang/include/clang/AST/Decl.h:313
 
+  /// Returns only qualifier from printQualifiedName, including the :: at the
+  /// end. E.g.

This doesn't return anything, so I think a better way to phrase the comment is 
"Prints only the nested name specifier, including a trailing :: at the end. 
e.g., if printQualifiedName(D) prints "A::B::i", this function prints "A::B::".`



Comment at: clang/include/clang/AST/Decl.h:317-318
+  ///this function returns "A::B::".
+  void printQualifier(raw_ostream &OS) const;
+  void printQualifier(raw_ostream &OS, const PrintingPolicy &Policy) const;
+

I'm not keen on "qualifier" here because types have qualifiers. How about 
`printNestedNameSpecifier()`?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67825



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67825: [AST] Extract Decl::printNestedNameSpecifier helper from Decl::printQualifiedName

2019-09-20 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov updated this revision to Diff 221002.
ilya-biryukov marked 4 inline comments as done.
ilya-biryukov added a comment.

- Update comments
- Rename new function to printNestedNameSpecifier


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67825

Files:
  clang/include/clang/AST/Decl.h
  clang/lib/AST/Decl.cpp


Index: clang/lib/AST/Decl.cpp
===
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -1558,6 +1558,19 @@
 
 void NamedDecl::printQualifiedName(raw_ostream &OS,
const PrintingPolicy &P) const {
+  printNestedNameSpecifier(OS, P);
+  if (getDeclName() || isa(this))
+OS << *this;
+  else
+OS << "(anonymous)";
+}
+
+void NamedDecl::printNestedNameSpecifier(raw_ostream &OS) const {
+  printNestedNameSpecifier(OS, getASTContext().getPrintingPolicy());
+}
+
+void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
+ const PrintingPolicy &P) const {
   const DeclContext *Ctx = getDeclContext();
 
   // For ObjC methods and properties, look through categories and use the
@@ -1571,10 +1584,8 @@
 Ctx = ID;
   }
 
-  if (Ctx->isFunctionOrMethod()) {
-printName(OS);
+  if (Ctx->isFunctionOrMethod())
 return;
-  }
 
   using ContextsTy = SmallVector;
   ContextsTy Contexts;
@@ -1644,11 +1655,6 @@
 }
 OS << "::";
   }
-
-  if (getDeclName() || isa(this))
-OS << *this;
-  else
-OS << "(anonymous)";
 }
 
 void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
Index: clang/include/clang/AST/Decl.h
===
--- clang/include/clang/AST/Decl.h
+++ clang/include/clang/AST/Decl.h
@@ -310,6 +310,14 @@
   void printQualifiedName(raw_ostream &OS) const;
   void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
 
+  /// Print only the nested name specifier part of a fully-qualified name,
+  /// including the '::' at the end. E.g.
+  ///when `printQualifiedName(D)` prints "A::B::i",
+  ///this function prints "A::B::".
+  void printNestedNameSpecifier(raw_ostream &OS) const;
+  void printNestedNameSpecifier(raw_ostream &OS,
+const PrintingPolicy &Policy) const;
+
   // FIXME: Remove string version.
   std::string getQualifiedNameAsString() const;
 


Index: clang/lib/AST/Decl.cpp
===
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -1558,6 +1558,19 @@
 
 void NamedDecl::printQualifiedName(raw_ostream &OS,
const PrintingPolicy &P) const {
+  printNestedNameSpecifier(OS, P);
+  if (getDeclName() || isa(this))
+OS << *this;
+  else
+OS << "(anonymous)";
+}
+
+void NamedDecl::printNestedNameSpecifier(raw_ostream &OS) const {
+  printNestedNameSpecifier(OS, getASTContext().getPrintingPolicy());
+}
+
+void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
+ const PrintingPolicy &P) const {
   const DeclContext *Ctx = getDeclContext();
 
   // For ObjC methods and properties, look through categories and use the
@@ -1571,10 +1584,8 @@
 Ctx = ID;
   }
 
-  if (Ctx->isFunctionOrMethod()) {
-printName(OS);
+  if (Ctx->isFunctionOrMethod())
 return;
-  }
 
   using ContextsTy = SmallVector;
   ContextsTy Contexts;
@@ -1644,11 +1655,6 @@
 }
 OS << "::";
   }
-
-  if (getDeclName() || isa(this))
-OS << *this;
-  else
-OS << "(anonymous)";
 }
 
 void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
Index: clang/include/clang/AST/Decl.h
===
--- clang/include/clang/AST/Decl.h
+++ clang/include/clang/AST/Decl.h
@@ -310,6 +310,14 @@
   void printQualifiedName(raw_ostream &OS) const;
   void printQualifiedName(raw_ostream &OS, const PrintingPolicy &Policy) const;
 
+  /// Print only the nested name specifier part of a fully-qualified name,
+  /// including the '::' at the end. E.g.
+  ///when `printQualifiedName(D)` prints "A::B::i",
+  ///this function prints "A::B::".
+  void printNestedNameSpecifier(raw_ostream &OS) const;
+  void printNestedNameSpecifier(raw_ostream &OS,
+const PrintingPolicy &Policy) const;
+
   // FIXME: Remove string version.
   std::string getQualifiedNameAsString() const;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67825: [AST] Extract Decl::printNestedNameSpecifier helper from Decl::printQualifiedName

2019-09-20 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added inline comments.



Comment at: clang/include/clang/AST/Decl.h:313
 
+  /// Returns only qualifier from printQualifiedName, including the :: at the
+  /// end. E.g.

aaron.ballman wrote:
> This doesn't return anything, so I think a better way to phrase the comment 
> is "Prints only the nested name specifier, including a trailing :: at the 
> end. e.g., if printQualifiedName(D) prints "A::B::i", this function prints 
> "A::B::".`
Good point, thanks!



Comment at: clang/include/clang/AST/Decl.h:317-318
+  ///this function returns "A::B::".
+  void printQualifier(raw_ostream &OS) const;
+  void printQualifier(raw_ostream &OS, const PrintingPolicy &Policy) const;
+

aaron.ballman wrote:
> I'm not keen on "qualifier" here because types have qualifiers. How about 
> `printNestedNameSpecifier()`?
Now I understand why we clang uses 'nested name specifier' everywhere!
Renamed per your suggestions.
FWIW, I would rather use `NameQualifier` and `TypeQualifier` to disambiguate 
between the two.
`NestedNameSpecifier` is a bit too long for my taste. But happy to stick with 
the conventions in the codebase.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67825



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67825: [AST] Extract Decl::printNestedNameSpecifier helper from Decl::printQualifiedName

2019-09-20 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet accepted this revision.
kadircet added a comment.
This revision is now accepted and ready to land.

LGTM, I know it is trivial, but some more unittests wouldn't hurt anyone :D

Also could you update the summary to mention "doing string manipulations in the 
presence of template arguments is hard?"


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67825



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67825: [AST] Extract Decl::printNestedNameSpecifier helper from Decl::printQualifiedName

2019-09-20 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov added a comment.

In D67825#1676528 , @kadircet wrote:

> LGTM, I know it is trivial, but some more unittests wouldn't hurt anyone :D


Yeah, good point, I'll add a few besides tests for `printQualifiedName`.

> Also could you update the summary to mention "doing string manipulations in 
> the presence of template arguments is hard?"

Done.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67825



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67825: [AST] Extract Decl::printNestedNameSpecifier helper from Decl::printQualifiedName

2019-09-20 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.

LGTM!




Comment at: clang/include/clang/AST/Decl.h:317-318
+  ///this function returns "A::B::".
+  void printQualifier(raw_ostream &OS) const;
+  void printQualifier(raw_ostream &OS, const PrintingPolicy &Policy) const;
+

ilya-biryukov wrote:
> aaron.ballman wrote:
> > I'm not keen on "qualifier" here because types have qualifiers. How about 
> > `printNestedNameSpecifier()`?
> Now I understand why we clang uses 'nested name specifier' everywhere!
> Renamed per your suggestions.
> FWIW, I would rather use `NameQualifier` and `TypeQualifier` to disambiguate 
> between the two.
> `NestedNameSpecifier` is a bit too long for my taste. But happy to stick with 
> the conventions in the codebase.
I think it'd be a pretty large undertaking to hit all of the places where we 
talk about qualifiers to get to the point where that distinction makes sense. I 
think we should just stick with nested name specifier, as that's a term of art 
from the standard for this concept.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67825



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67825: [AST] Extract Decl::printNestedNameSpecifier helper from Decl::printQualifiedName

2019-09-20 Thread Ilya Biryukov via Phabricator via cfe-commits
ilya-biryukov marked 2 inline comments as done.
ilya-biryukov added inline comments.



Comment at: clang/include/clang/AST/Decl.h:317-318
+  ///this function returns "A::B::".
+  void printQualifier(raw_ostream &OS) const;
+  void printQualifier(raw_ostream &OS, const PrintingPolicy &Policy) const;
+

aaron.ballman wrote:
> ilya-biryukov wrote:
> > aaron.ballman wrote:
> > > I'm not keen on "qualifier" here because types have qualifiers. How about 
> > > `printNestedNameSpecifier()`?
> > Now I understand why we clang uses 'nested name specifier' everywhere!
> > Renamed per your suggestions.
> > FWIW, I would rather use `NameQualifier` and `TypeQualifier` to 
> > disambiguate between the two.
> > `NestedNameSpecifier` is a bit too long for my taste. But happy to stick 
> > with the conventions in the codebase.
> I think it'd be a pretty large undertaking to hit all of the places where we 
> talk about qualifiers to get to the point where that distinction makes sense. 
> I think we should just stick with nested name specifier, as that's a term of 
> art from the standard for this concept.
Fully agree, it's too late to change it at this point.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67825



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67737: [clang-tidy] Add check for classes missing -hash ⚠️

2019-09-20 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM!




Comment at: clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp:56
+  const auto *ID = Result.Nodes.getNodeAs("impl");
+  diag(ID->getLocation(), "%0 implements -isEqual: without implementing -hash")
+  << ID;

stephanemoore wrote:
> aaron.ballman wrote:
> > Do you think we could generate a fixit to add the `hash` method? Do you 
> > think we could even add a default implementation that returns the pointer 
> > to the object (assuming that's the correct default behavior)?
> > Do you think we could generate a fixit to add the hash method?
> 
> I think it would be pretty tough to generate a reasonable hash method without 
> knowing the equality and hashing semantics that the scenario calls for.
> 
> Here is an analogous situation presented in C++ (please excuse the hastily 
> assembled sample code):
> ```
> namespace {
> 
> class NSObject {
>   public:
> NSObject() {}
> virtual ~NSObject() {}
> 
> virtual bool isEqual(const NSObject *other) const {
>   return this == other;
> }
> virtual unsigned long long hash() const {
>   return (unsigned long long)this;
> }
> };
> 
> }
> 
> #include 
> #include 
> 
> namespace {
> 
> class Movie : public virtual NSObject {
>   private:
> std::string name;
> std::string language;
> 
>   public:
> Movie(std::string name, std::string language) : name(name), 
> language(language) {}
> ~Movie() override {}
> bool isEqual(const NSObject *other) const override {
>   if (auto otherMovie = dynamic_cast(other)) {
> // Movies with the same name are considered equal
> // regardless of the language of the screening.
> return name == otherMovie->name;
>   }
>   return false;
> }
> unsigned long long hash() const override {
>   return name.length();
> }
> };
> 
> }
> ```
> 
> As before, the base class uses pointer equality and the pointer as a hash. A 
> subclass may arbitrarily add additional state but only the developer knows 
> which added state factors into equality operations and consequently should be 
> considered—but not necessarily required—in the hash operation. The matter can 
> technically get even more complicated if an object stores state externally. I 
> would hope that externally stored state would not factor into the equality 
> operation of an object but I hesitate to make an assumption.
> 
> The developer is also in the best position to prioritize different properties 
> of the hash function including performance, collision resistance, uniformity, 
> and non-invertibility.
> 
> Writing effective hash functions is probably difficult independent of the 
> programming language but it might help to consider some specific examples in 
> Objective-C. 
> [GPBMessage](https://github.com/protocolbuffers/protobuf/blob/ffa6bfc/objectivec/GPBMessage.m),
>  the Objective-C base class for Google Protocol Buffer message classes, 
> implements `-hash` but has an [extensive 
> comment](https://github.com/protocolbuffers/protobuf/blob/ffa6bfc/objectivec/GPBMessage.m#L2749)
>  explaining that its complex but generic implementation is not generally 
> optimal and recommends that developers override `-hash` and `-isEqual:` to 
> optimize for runtime performance. In contrast, the basic collection classes 
> in Apple's Foundation framework have [surprisingly simple hash 
> behavior](https://github.com/stephanemoore/archives/blob/master/objc/tips/hashing-basic-collections.md)
>  that clearly indicate priority to runtime performance over uniformity and 
> collision resistance. The former is a conservatively expensive hash function 
> and the latter is a conservatively inexpensive hash function.
> 
> > Do you think we could even add a default implementation that returns the 
> > pointer to the object (assuming that's the correct default behavior)?
> 
> A hash returning the object pointer is already inherited from the superclass 
> (i..e, `-[NSObject hash]`). Defining an override that returns the object 
> pointer would be a functional no-op for classes directly derived from 
> `NSObject` (although the explicit override could be useful as a signal of 
> intended behavior).
> A hash returning the object pointer is already inherited from the superclass 
> (i..e, -[NSObject hash]). Defining an override that returns the object 
> pointer would be a functional no-op for classes directly derived from 
> NSObject (although the explicit override could be useful as a signal of 
> intended behavior).

Ah, my ObjC knowledge is weak and I was thinking that the one inherited from 
`NSObject` would be hidden. Thank you for the detailed explanation, that makes 
a lot of sense to me.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67737



___

[PATCH] D67501: [clang-tidy] Fix relative path in header-filter.

2019-09-20 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr accepted this revision.
gribozavr added a comment.
This revision is now accepted and ready to land.

Thanks! Please let me know if you need me to commit the patch for you.


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

https://reviews.llvm.org/D67501



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67632: [libTooling] Introduce new library of source-code builders.

2019-09-20 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr added inline comments.



Comment at: clang/include/clang/Tooling/Refactoring/SourceCodeBuilders.h:9
+///
+/// /file
+/// This file collects facilities for generating source-code strings.

"\file"



Comment at: clang/include/clang/Tooling/Refactoring/SourceCodeBuilders.h:10
+/// /file
+/// This file collects facilities for generating source-code strings.
+///

"source code"



Comment at: clang/include/clang/Tooling/Refactoring/SourceCodeBuilders.h:30
+
+/// Determines whether printing this expression in *any* expression requires a
+/// parentheses to preserve its meaning. This analyses is necessarily

s/a//

or s/a parentheses/a pair of parentheses/



Comment at: clang/include/clang/Tooling/Refactoring/SourceCodeBuilders.h:33
+/// conservative because it lacks information about the target context.
+bool mayNeedParens(const Expr &E);
+

`mayEverNeedParens`? (to emphasize conservativeness and lack of context)



Comment at: clang/include/clang/Tooling/Refactoring/SourceCodeBuilders.h:56
+/// Builds idiomatic source for the dereferencing of `E`: prefix with `*` but
+/// simplify when it already begins with `&`.  \returns empty string on 
failure.
+std::string buildDereference(const Expr &E, const ASTContext &Context);

Given that empty string is returned in a vanishingly small number of cases, it 
would be worth it returning `llvm::Optional` to force the caller 
to handle the failure.



Comment at: clang/lib/Tooling/Refactoring/SourceCodeBuilders.cpp:77
+
+  if (Text.empty()) return std::string();
+  // Add leading '*'.

ymandel wrote:
> Eugene.Zelenko wrote:
> > Could return {}. Same in other places. By the word, did you run 
> > Clang-format over code?
> No, thanks for pointing that out.
> 
> I find `return std::string()` more readable, because it doesn't require that 
> I check/know the return type of the function. But, if `return {}` is 
> standard, I'm fine changing it. What's most common in the clang source?
I personally find `return "";` more readable. After all, we don't care about 
the specific type, we want to express that we return an empty string. The most 
natural way to write an empty string is a string literal `""`.



Comment at: clang/lib/Tooling/Refactoring/SourceCodeBuilders.cpp:21
+// Ignores implicit object-construction expressions in addition to the normal
+// implicit expressions that are ignored.
+const Expr *tooling::reallyIgnoreImplicit(const Expr &E) {

No need to repeat the comment from the header.



Comment at: clang/lib/Tooling/Refactoring/SourceCodeBuilders.cpp:68
+std::string tooling::buildParens(const Expr &E, const ASTContext &Context) {
+  StringRef ExprText = getText(E, Context);
+  if (mayNeedParens(E))

`buildDereference` below checks for `getText` returning an empty string; this 
function does not. Why?



Comment at: clang/unittests/Tooling/SourceCodeBuildersTest.cpp:23
+
+// Create a valid translation-unit from a statement.
+static std::string wrapSnippet(StringRef StatementCode) {

"translation unit"



Comment at: clang/unittests/Tooling/SourceCodeBuildersTest.cpp:76
+  testPredicate(needParensAfterUnaryOperator, "3 + 5;", true);
+  testPredicate(needParensAfterUnaryOperator, "true ? 3 : 5;", true);
+

Also need tests for:
- overloaded binary operator `S(10) + S(20)`
- implicit conversions `void takeS(S); takeS(10 + 20);`



Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67632



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67501: [clang-tidy] Fix relative path in header-filter.

2019-09-20 Thread Yubo Xie via Phabricator via cfe-commits
xyb added a comment.

Yes, I need your help to submit the patch. I don't have the permission. Thanks.


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

https://reviews.llvm.org/D67501



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372386 - [StaticAnalyzer] Use llvm::StringLiteral instead of StringRef in few places

2019-09-20 Thread Benjamin Kramer via cfe-commits
Author: d0k
Date: Fri Sep 20 05:59:29 2019
New Revision: 372386

URL: http://llvm.org/viewvc/llvm-project?rev=372386&view=rev
Log:
[StaticAnalyzer] Use llvm::StringLiteral instead of StringRef in few places

StringRef's constexpr constructor seems to be extremely slow in MSVC
2017, so don't use it for generated tables. Should make PR43369 a bit
better, no functionality change.

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=372386&r1=372385&r2=372386&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Fri Sep 20 
05:59:29 2019
@@ -278,13 +278,13 @@ public:
 
   // Create an array of all -analyzer-config command line options. Sort it in
   // the constructor.
-  std::vector AnalyzerConfigCmdFlags = {
+  std::vector AnalyzerConfigCmdFlags = {
 #define ANALYZER_OPTION_DEPENDS_ON_USER_MODE(TYPE, NAME, CMDFLAG, DESC,
\
  SHALLOW_VAL, DEEP_VAL)
\
   ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, SHALLOW_VAL)
 
 #define ANALYZER_OPTION(TYPE, NAME, CMDFLAG, DESC, DEFAULT_VAL)
\
-CMDFLAG,
+  llvm::StringLiteral(CMDFLAG),
 
 #include "clang/StaticAnalyzer/Core/AnalyzerOptions.def"
 #undef ANALYZER_OPTION
@@ -415,9 +415,10 @@ inline UserModeKind AnalyzerOptions::get
 
 inline std::vector
 AnalyzerOptions::getRegisteredCheckers(bool IncludeExperimental) {
-  static const StringRef StaticAnalyzerCheckerNames[] = {
+  static constexpr llvm::StringLiteral StaticAnalyzerCheckerNames[] = {
 #define GET_CHECKERS
-#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) FULLNAME,
+#define CHECKER(FULLNAME, CLASS, HELPTEXT, DOC_URI, IS_HIDDEN) 
\
+  llvm::StringLiteral(FULLNAME),
 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
 #undef CHECKER
 #undef GET_CHECKERS
@@ -433,9 +434,9 @@ AnalyzerOptions::getRegisteredCheckers(b
 
 inline std::vector
 AnalyzerOptions::getRegisteredPackages(bool IncludeExperimental) {
-  static const StringRef StaticAnalyzerPackageNames[] = {
+  static constexpr llvm::StringLiteral StaticAnalyzerPackageNames[] = {
 #define GET_PACKAGES
-#define PACKAGE(FULLNAME) FULLNAME,
+#define PACKAGE(FULLNAME) llvm::StringLiteral(FULLNAME),
 #include "clang/StaticAnalyzer/Checkers/Checkers.inc"
 #undef PACKAGE
 #undef GET_PACKAGES


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67635: Fix for stringized function-macro args continued across lines

2019-09-20 Thread Kousik Kumar via Phabricator via cfe-commits
kousikk added a comment.

> I think you should obtain commit access for your future patches/commits. You 
> can follow the instructions here: 
> https://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access

Thanks, I've done that!


Repository:
  rL LLVM

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

https://reviews.llvm.org/D67635



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67621: [libTooling] Add `ifBound`, `elseBranch` RangeSelector combinators.

2019-09-20 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr accepted this revision.
gribozavr added inline comments.
This revision is now accepted and ready to land.



Comment at: clang/lib/Tooling/Refactoring/RangeSelector.cpp:320
+  };
+}

May I ask to keep the implementation order consistent with the header file?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67621



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372387 - [SystemZ] Add SystemZ as supporting target in help text for -mfentry.

2019-09-20 Thread Jonas Paulsson via cfe-commits
Author: jonpa
Date: Fri Sep 20 06:13:50 2019
New Revision: 372387

URL: http://llvm.org/viewvc/llvm-project?rev=372387&view=rev
Log:
[SystemZ]  Add SystemZ as supporting target in help text for -mfentry.

=> "Insert calls to fentry at function entry (x86/SystemZ only)"

Review: Ulrich Weigand

Modified:
cfe/trunk/docs/ClangCommandLineReference.rst
cfe/trunk/include/clang/Driver/Options.td

Modified: cfe/trunk/docs/ClangCommandLineReference.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ClangCommandLineReference.rst?rev=372387&r1=372386&r2=372387&view=diff
==
--- cfe/trunk/docs/ClangCommandLineReference.rst (original)
+++ cfe/trunk/docs/ClangCommandLineReference.rst Fri Sep 20 06:13:50 2019
@@ -2194,7 +2194,7 @@ Set EABI type, e.g. 4, 5 or gnu (default
 
 .. option:: -mfentry
 
-Insert calls to fentry at function entry (x86 only)
+Insert calls to fentry at function entry (x86/SystemZ only)
 
 .. option:: -mfloat-abi=
 

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=372387&r1=372386&r2=372387&view=diff
==
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Fri Sep 20 06:13:50 2019
@@ -2387,7 +2387,7 @@ def mpie_copy_relocations : Flag<["-"],
   Flags<[CC1Option]>,
   HelpText<"Use copy relocations support for PIE builds">;
 def mno_pie_copy_relocations : Flag<["-"], "mno-pie-copy-relocations">, 
Group;
-def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at 
function entry (x86 only)">,
+def mfentry : Flag<["-"], "mfentry">, HelpText<"Insert calls to fentry at 
function entry (x86/SystemZ only)">,
   Flags<[CC1Option]>, Group;
 def mips16 : Flag<["-"], "mips16">, Group;
 def mno_mips16 : Flag<["-"], "mno-mips16">, Group;


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67830: [AArch64][SVE] Implement punpk[hi|lo] intrinsics

2019-09-20 Thread Kerry McLaughlin via Phabricator via cfe-commits
kmclaughlin created this revision.
kmclaughlin added reviewers: sdesmalen, rovka.
Herald added subscribers: psnobl, rkruppe, hiraditya, kristof.beyls, tschuett.
Herald added a reviewer: rengolin.
Herald added a project: LLVM.

Adds the following two intrinsics:

- int_aarch64_sve_punpkhi
- int_aarch64_sve_punpklo

This patch also contains a fix which allows LLVMHalfElementsVectorType
to forward reference overloadable arguments.


Repository:
  rL LLVM

https://reviews.llvm.org/D67830

Files:
  llvm/include/llvm/IR/IntrinsicsAArch64.td
  llvm/lib/IR/Function.cpp
  llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
  llvm/lib/Target/AArch64/SVEInstrFormats.td
  llvm/test/CodeGen/AArch64/sve-intrinsics-pred-operations.ll

Index: llvm/test/CodeGen/AArch64/sve-intrinsics-pred-operations.ll
===
--- /dev/null
+++ llvm/test/CodeGen/AArch64/sve-intrinsics-pred-operations.ll
@@ -0,0 +1,65 @@
+; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
+
+;
+; PUNPKHI
+;
+
+define  @punpkhi_b16( %a) {
+; CHECK-LABEL: punpkhi_b16
+; CHECK: punpkhi p0.h, p0.b
+; CHECK-NEXT: ret
+  %res = call  @llvm.aarch64.sve.punpkhi.nxv8i1( %a)
+  ret  %res
+}
+
+define  @punpkhi_b8( %a) {
+; CHECK-LABEL: punpkhi_b8
+; CHECK: punpkhi p0.h, p0.b
+; CHECK-NEXT: ret
+  %res = call  @llvm.aarch64.sve.punpkhi.nxv4i1( %a)
+  ret  %res
+}
+
+define  @punpkhi_b4( %a) {
+; CHECK-LABEL: punpkhi_b4
+; CHECK: punpkhi p0.h, p0.b
+; CHECK-NEXT: ret
+  %res = call  @llvm.aarch64.sve.punpkhi.nxv2i1( %a)
+  ret  %res
+}
+
+;
+; PUNPKLO
+;
+
+define  @punpklo_b16( %a) {
+; CHECK-LABEL: punpklo_b16
+; CHECK: punpklo p0.h, p0.b
+; CHECK-NEXT: ret
+  %res = call  @llvm.aarch64.sve.punpklo.nxv8i1( %a)
+  ret  %res
+}
+
+define  @punpklo_b8( %a) {
+; CHECK-LABEL: punpklo_b8
+; CHECK: punpklo p0.h, p0.b
+; CHECK-NEXT: ret
+  %res = call  @llvm.aarch64.sve.punpklo.nxv4i1( %a)
+  ret  %res
+}
+
+define  @punpklo_b4( %a) {
+; CHECK-LABEL: punpklo_b4
+; CHECK: punpklo p0.h, p0.b
+; CHECK-NEXT: ret
+  %res = call  @llvm.aarch64.sve.punpklo.nxv2i1( %a)
+  ret  %res
+}
+
+declare  @llvm.aarch64.sve.punpkhi.nxv8i1()
+declare  @llvm.aarch64.sve.punpkhi.nxv4i1()
+declare  @llvm.aarch64.sve.punpkhi.nxv2i1()
+
+declare  @llvm.aarch64.sve.punpklo.nxv8i1()
+declare  @llvm.aarch64.sve.punpklo.nxv4i1()
+declare  @llvm.aarch64.sve.punpklo.nxv2i1()
Index: llvm/lib/Target/AArch64/SVEInstrFormats.td
===
--- llvm/lib/Target/AArch64/SVEInstrFormats.td
+++ llvm/lib/Target/AArch64/SVEInstrFormats.td
@@ -283,6 +283,11 @@
 // SVE pattern match helpers.
 //===--===//
 
+class SVE_1_Op_Pat
+: Pat<(vtd (op vt1:$Op1)),
+  (inst $Op1)>;
+
 class SVE_3_Op_Pat
 : Pat<(vtd (op vt1:$Op1, vt2:$Op2, vt3:$Op3)),
@@ -4280,6 +4285,14 @@
   let Inst{3-0}   = Pd;
 }
 
+multiclass sve_int_perm_punpk {
+  def NAME : sve_int_perm_punpk;
+
+  def : SVE_1_Op_Pat(NAME)>;
+  def : SVE_1_Op_Pat(NAME)>;
+  def : SVE_1_Op_Pat(NAME)>;
+}
+
 class sve_int_rdffr_pred
 : I<(outs PPR8:$Pd), (ins PPRAny:$Pg),
   asm, "\t$Pd, $Pg/z",
Index: llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
===
--- llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
+++ llvm/lib/Target/AArch64/AArch64SVEInstrInfo.td
@@ -216,8 +216,8 @@
   defm UUNPKLO_ZZ : sve_int_perm_unpk<0b10, "uunpklo">;
   defm UUNPKHI_ZZ : sve_int_perm_unpk<0b11, "uunpkhi">;
 
-  def  PUNPKLO_PP : sve_int_perm_punpk<0b0, "punpklo">;
-  def  PUNPKHI_PP : sve_int_perm_punpk<0b1, "punpkhi">;
+  defm PUNPKLO_PP : sve_int_perm_punpk<0b0, "punpklo", int_aarch64_sve_punpklo>;
+  defm PUNPKHI_PP : sve_int_perm_punpk<0b1, "punpkhi", int_aarch64_sve_punpkhi>;
 
   defm MOVPRFX_ZPzZ : sve_int_movprfx_pred_zero<0b000, "movprfx">;
   defm MOVPRFX_ZPmZ : sve_int_movprfx_pred_merge<0b001, "movprfx">;
Index: llvm/lib/IR/Function.cpp
===
--- llvm/lib/IR/Function.cpp
+++ llvm/lib/IR/Function.cpp
@@ -1210,8 +1210,9 @@
 }
 case IITDescriptor::HalfVecArgument:
   // If this is a forward reference, defer the check for later.
-  return D.getArgumentNumber() >= ArgTys.size() ||
- !isa(ArgTys[D.getArgumentNumber()]) ||
+  if (D.getArgumentNumber() >= ArgTys.size())
+return IsDeferredCheck || DeferCheck(Ty);
+  return !isa(ArgTys[D.getArgumentNumber()]) ||
  VectorType::getHalfElementsVectorType(
  cast(ArgTys[D.getArgumentNumber()])) != Ty;
 case IITDescriptor::SameVecWidthArgument: {
Index: llvm/include/llvm/IR/IntrinsicsAArch64.td
===
--- llvm/include/llvm/IR/IntrinsicsAArch64.td
+++ llvm/include/llvm/IR/IntrinsicsAArch64.td
@@ -768,6 +768,11 @@
  LLVMMatchType<0>],
 [IntrNoMem]>;
 
+  cla

[clang-tools-extra] r372388 - [clang-tidy] Fix relative path in header-filter.

2019-09-20 Thread Dmitri Gribenko via cfe-commits
Author: gribozavr
Date: Fri Sep 20 06:19:32 2019
New Revision: 372388

URL: http://llvm.org/viewvc/llvm-project?rev=372388&view=rev
Log:
[clang-tidy] Fix relative path in header-filter.

Summary:
Clang-tidy supports output diagnostics from header files if user
specifies --header-filter. But it can't handle relative path well.
For example, the folder structure of a project is:

```
// a.h is in /src/a/a.h

// b.h is in /src/b/b.h
...

// c.cpp is in /src/c.cpp

```

Now, we set --header-filter as --header-filter=/a/. That means we only
want to check header files under /src/a/ path, and ignore header files
uder /src/b/ path, but in current implementation, clang-tidy will check
/src/b/b.h also, because the name of b.h used in clang-tidy is
/src/a/../b/b.h.

This change tries to fix this issue.

Reviewers: alexfh, hokein, aaron.ballman, gribozavr

Reviewed By: gribozavr

Subscribers: MyDeveloperDay, xazax.hun, cfe-commits

Tags: #clang, #clang-tools-extra

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

Patch by Yubo Xie.

Added:
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_a/

clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_a/header_a.h
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_b/

clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_b/header_b.h
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_c/

clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_c/header_c.h
Modified:
clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
clang-tools-extra/trunk/test/clang-tidy/file-filter.cpp

Modified: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp?rev=372388&r1=372387&r2=372388&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp Fri Sep 
20 06:19:32 2019
@@ -551,7 +551,9 @@ void ClangTidyDiagnosticConsumer::checkF
 return;
   }
 
-  StringRef FileName(File->getName());
+  StringRef FileName = File->tryGetRealPathName();
+  if (FileName.empty())
+FileName = File->getName();
   LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
Sources.isInMainFile(Location) ||
getHeaderFilter()->match(FileName);

Added: 
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_a/header_a.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_a/header_a.h?rev=372388&view=auto
==
--- 
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_a/header_a.h
 (added)
+++ 
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_a/header_a.h
 Fri Sep 20 06:19:32 2019
@@ -0,0 +1,3 @@
+#include "../subfolder_b/header_b.h"
+
+class SA { SA(int); };

Added: 
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_b/header_b.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_b/header_b.h?rev=372388&view=auto
==
--- 
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_b/header_b.h
 (added)
+++ 
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_b/header_b.h
 Fri Sep 20 06:19:32 2019
@@ -0,0 +1 @@
+class SB { SB(int); };

Added: 
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_c/header_c.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_c/header_c.h?rev=372388&view=auto
==
--- 
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_c/header_c.h
 (added)
+++ 
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_c/header_c.h
 Fri Sep 20 06:19:32 2019
@@ -0,0 +1 @@
+class SC { SC(int); };

Modified: clang-tools-extra/trunk/test/clang-tidy/file-filter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/file-filter.cpp?rev=372388&r1=372387&r2=372388&view=diff
==
--- clang-tools-extra/trunk/test/clang-tidy/file-filter.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/file-filter.cpp Fri Sep 20 06:19:32 
2019
@@ -9,6 +9,12 @@
 //   file-filter\header*.h due to code order between '/' and '\\'.
 // RUN: clang-tidy -checks='-*,google-explicit-constructor' 
-header-filter='.*' -system-headers %s -- -I %S/Inputs/file-filter/system/.. 
-isyst

[PATCH] D67501: [clang-tidy] Fix relative path in header-filter.

2019-09-20 Thread Dmitri Gribenko via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL372388: [clang-tidy] Fix relative path in header-filter. 
(authored by gribozavr, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D67501?vs=220997&id=221013#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D67501

Files:
  clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
  
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_a/header_a.h
  
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_b/header_b.h
  
clang-tools-extra/trunk/test/clang-tidy/Inputs/file-filter/subfolder_c/header_c.h
  clang-tools-extra/trunk/test/clang-tidy/file-filter.cpp

Index: clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
===
--- clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ clang-tools-extra/trunk/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -551,7 +551,9 @@
 return;
   }
 
-  StringRef FileName(File->getName());
+  StringRef FileName = File->tryGetRealPathName();
+  if (FileName.empty())
+FileName = File->getName();
   LastErrorRelatesToUserCode = LastErrorRelatesToUserCode ||
Sources.isInMainFile(Location) ||
getHeaderFilter()->match(FileName);
Index: clang-tools-extra/trunk/test/clang-tidy/file-filter.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/file-filter.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/file-filter.cpp
@@ -9,6 +9,12 @@
 //   file-filter\header*.h due to code order between '/' and '\\'.
 // RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4 %s
 // RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='.*' -system-headers -quiet %s -- -I %S/Inputs/file-filter/system/.. -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK4-QUIET %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_a' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK5 %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_a' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK5-QUIET %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_b' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK6 %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_b' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK6-QUIET %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_c' %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK7 %s
+// RUN: clang-tidy -checks='-*,google-explicit-constructor' -header-filter='subfolder_c' -quiet %s -- -I %S/Inputs/file-filter -isystem %S/Inputs/file-filter/system 2>&1 | FileCheck --check-prefix=CHECK7-QUIET %s
 
 #include "header1.h"
 // CHECK-NOT: warning:
@@ -19,6 +25,12 @@
 // CHECK3-QUIET-NOT: warning:
 // CHECK4: header1.h:1:12: warning: single-argument constructors
 // CHECK4-QUIET: header1.h:1:12: warning: single-argument constructors
+// CHECK5-NOT: warning:
+// CHECK5-QUIET-NOT: warning:
+// CHECK6-NOT: warning:
+// CHECK6-QUIET-NOT: warning:
+// CHECK7-NOT: warning:
+// CHECK7-QUIET-NOT: warning:
 
 #include "header2.h"
 // CHECK-NOT: warning:
@@ -29,6 +41,44 @@
 // CHECK3-QUIET: header2.h:1:12: warning: single-argument constructors
 // CHECK4: header2.h:1:12: warning: single-argument constructors
 // CHECK4-QUIET: header2.h:1:12: warning: single-argument constructors
+// CHECK5-NOT: warning:
+// CHECK5-QUIET-NOT: warning:
+// CHECK6-NOT: warning:
+// CHECK6-QUIET-NOT: warning:
+// CHECK7-NOT: warning:
+// CHECK7-QUIET-NOT: warning:
+
+#include "subfolder_a/header_a.h"
+// CHECK-NOT: warning:
+// CHECK-QUIET-NOT: warning:
+// CHECK2: header_b.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK2-QUIET: header_b.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK3-NOT: warning:
+// CHECK3-QUIET-NOT: warning:
+// CHECK4: header_b.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK4-QUIET: header_b.h:1:12: warning: single-argument constructors must be marked explicit
+// CHECK5: header_a.h:3:12: warning: single-argument constructo

[PATCH] D67052: Add reference type transformation builtins

2019-09-20 Thread Zoe Carver via Phabricator via cfe-commits
zoecarver updated this revision to Diff 221014.
zoecarver added a comment.
Herald added a subscriber: erik.pilkington.

- address review comments
- fix warnings in build


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67052

Files:
  clang/include/clang/AST/Type.h
  clang/include/clang/Basic/Specifiers.h
  clang/include/clang/Basic/TokenKinds.def
  clang/include/clang/Parse/Parser.h
  clang/include/clang/Sema/DeclSpec.h
  clang/lib/AST/ItaniumMangle.cpp
  clang/lib/AST/JSONNodeDumper.cpp
  clang/lib/AST/TextNodeDumper.cpp
  clang/lib/AST/TypePrinter.cpp
  clang/lib/Format/FormatToken.cpp
  clang/lib/Lex/PPMacroExpansion.cpp
  clang/lib/Parse/ParseDecl.cpp
  clang/lib/Parse/ParseDeclCXX.cpp
  clang/lib/Sema/DeclSpec.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaTemplateVariadic.cpp
  clang/lib/Sema/SemaType.cpp
  clang/test/SemaCXX/add_reference.cpp
  
libcxx/test/libcxx/utilities/meta/stress_tests/stress_test_add_lvalue_reference.sh.cpp
  
libcxx/test/libcxx/utilities/meta/stress_tests/stress_test_add_rvalue_reference.sh.cpp
  
libcxx/test/libcxx/utilities/meta/stress_tests/stress_test_remove_reference.sh.cpp

Index: libcxx/test/libcxx/utilities/meta/stress_tests/stress_test_remove_reference.sh.cpp
===
--- /dev/null
+++ libcxx/test/libcxx/utilities/meta/stress_tests/stress_test_remove_reference.sh.cpp
@@ -0,0 +1,63 @@
+//===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is a dummy feature that prevents this test from running by default.
+
+// The table below compares the compile time and object size for each of the
+// variants listed in the RUN script.
+//
+//  Impl   Compile Time  Object Size
+// --
+// new_remove_reference:   22.849 s  121 K
+// std::remove_reference:  25.643 s  121 K
+//
+// RUN: %cxx %flags %compile_flags -c %s -o %S/orig.o -ggdb  -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17
+// RUN: %cxx %flags %compile_flags -c %s -o %S/new.o -ggdb  -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17 -DTEST_NEW
+
+#include 
+#include 
+
+#include "test_macros.h"
+#include "template_cost_testing.h"
+
+template  struct Arg { enum { value = 1 }; };
+
+#ifdef TEST_NEW
+
+template 
+struct new_remove_reference
+{
+  typedef __remove_reference(T) type;
+};
+
+#define TEST_CASE_NOP()  new_remove_reference< Arg< __COUNTER__ > >{},
+#define TEST_CASE_TYPE() typename new_remove_reference< Arg< __COUNTER__ > >::type,
+
+#else
+
+#define TEST_CASE_NOP()  std::remove_reference< Arg< __COUNTER__ > >{},
+#define TEST_CASE_TYPE() typename std::remove_reference< Arg< __COUNTER__ > >::type,
+
+#endif
+
+int sink(...);
+
+int x = sink(
+  REPEAT_1(TEST_CASE_NOP)
+  REPEAT_1(TEST_CASE_NOP) 42
+);
+
+void Foo( REPEAT_1(TEST_CASE_TYPE) int) { }
+
+void escape() {
+
+sink(&x);
+sink(&Foo);
+}
+
+
Index: libcxx/test/libcxx/utilities/meta/stress_tests/stress_test_add_rvalue_reference.sh.cpp
===
--- /dev/null
+++ libcxx/test/libcxx/utilities/meta/stress_tests/stress_test_add_rvalue_reference.sh.cpp
@@ -0,0 +1,63 @@
+//===--===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+//
+// This is a dummy feature that prevents this test from running by default.
+
+// The table below compares the compile time and object size for each of the
+// variants listed in the RUN script.
+//
+//  Impl   Compile Time  Object Size
+// --
+// new_add_rvalue_reference:   56.398 s  171 K
+// std::add_rvalue_reference:  114.59 s  271 K
+//
+// RUN: %cxx %flags %compile_flags -c %s -o %S/orig.o -ggdb  -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17
+// RUN: %cxx %flags %compile_flags -c %s -o %S/new.o -ggdb  -ggnu-pubnames -ftemplate-depth=5000 -ftime-trace -std=c++17 -DTEST_NEW
+
+#include 
+#include 
+
+#include "test_macros.h"
+#include "template_cost_testing.h"
+
+template  struct Arg { enum { value = 1 }; };
+
+#ifdef TEST_NEW
+
+template 
+struct new_add_rvalue_reference
+{
+  typedef __add_rvalue_reference(T) type;
+};
+
+#define TEST_CASE_

[PATCH] D67052: Add reference type transformation builtins

2019-09-20 Thread Zoe Carver via Phabricator via cfe-commits
zoecarver marked an inline comment as done.
zoecarver added inline comments.



Comment at: clang/lib/AST/ItaniumMangle.cpp:3412
 break;
+  case UnaryTransformType::RemoveReferenceType:
+Out << "3err";

Eric, I looked at your comment, but it seems that we no longer unary type 
transformations that way. @rsmith is this correct? 


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67052



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67830: [AArch64][SVE] Implement punpk[hi|lo] intrinsics

2019-09-20 Thread Sander de Smalen via Phabricator via cfe-commits
sdesmalen accepted this revision.
sdesmalen added a comment.
This revision is now accepted and ready to land.

LGTM. Looks like a straightforward fix and support for `punpk(hi|lo)` 
intrinsics.




Comment at: llvm/lib/IR/Function.cpp:1213
   // If this is a forward reference, defer the check for later.
-  return D.getArgumentNumber() >= ArgTys.size() ||
- !isa(ArgTys[D.getArgumentNumber()]) ||
+  if (D.getArgumentNumber() >= ArgTys.size())
+return IsDeferredCheck || DeferCheck(Ty);

Nice find!



Comment at: llvm/test/CodeGen/AArch64/sve-intrinsics-pred-operations.ll:1
+; RUN: llc -mtriple=aarch64-linux-gnu -mattr=+sve < %s | FileCheck %s
+

nit: You've added the file `sve-intrinsics-pred-operations.ll`. Is it worth 
putting these in a separate directory and separate out the tests per intrinsic, 
e.g. `test/CodeGen/AArch64/SVE/sve-intrinsics-punpkhi.ll`


Repository:
  rL LLVM

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

https://reviews.llvm.org/D67830



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67632: [libTooling] Introduce new library of source-code builders.

2019-09-20 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel marked an inline comment as done.
ymandel added a comment.

Thanks for the review!  Agreed on all points and then some -- next revision 
will have a bunch of cleanups. I think the only major issue is the return type. 
See below.




Comment at: clang/lib/Tooling/Refactoring/SourceCodeBuilders.cpp:68
+std::string tooling::buildParens(const Expr &E, const ASTContext &Context) {
+  StringRef ExprText = getText(E, Context);
+  if (mayNeedParens(E))

gribozavr wrote:
> `buildDereference` below checks for `getText` returning an empty string; this 
> function does not. Why?
Regarding this and the issue of returning `llvm::Optional`: the code overall is 
rather inconsistent in its handling of empty strings returned from `getText`. 
This is only one example.

sorry for this -- this code was mostly collected from various other places in 
the codebase and I should have looked it over more carefully.

With that said -- I think we need to decide whether we systematically assume 
that `getText` doesn't return an empty string, or systematically check for it 
and return llvm::None in that case.  We have the choice becuase there is no 
risk of UB from ignoring the empty text.   Any checks in the code seem only 
designed to propagate the "emptiness" for the caller's sake.

I'm inclined to state a precondition on the all of the functions that 
`getText(E)` is non empty, rather than sprinkle optionals throughout the API. 
My reasoning is that checking the result of these functions is "too late" in 
the process. A failure here is caused by passing a node that has no 
corresponding source code. If the caller is potentially dealing with such 
phantom nodes, they should know that before trying to construct code with them. 
Any check they can do on the result of `getText` they should have done earlier 
with a more appropriate predicate of the node.

That said, I understand the preference for defensiveness (don't assume the 
caller will get it right). I'm also fine with a compromise of asserting the 
non-emptiness of any internal call to `getText` although that might be almost 
as messy as just handling it.

WDYT?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67632



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67833: [OpenMP 5.0] Codegen support to pass user-defined mapper functions to runtime

2019-09-20 Thread Lingda Li via Phabricator via cfe-commits
lildmh created this revision.
Herald added subscribers: cfe-commits, guansong.
Herald added a reviewer: jdoerfert.
Herald added a project: clang.

This patch implements the code generation to use OpenMP 5.0 declare mapper 
(e.g., user-defined mapper) constructs. It looks up the proper mapper function 
for each map, to, or from clause that has a user-defined mapper associated, and 
passes them to the OpenMP runtime function.
The design slides can be found at 
https://github.com/lingda-li/public-sharing/blob/master/mapper_runtime_design.pptx


Repository:
  rC Clang

https://reviews.llvm.org/D67833

Files:
  include/clang/AST/OpenMPClause.h
  lib/CodeGen/CGOpenMPRuntime.cpp
  lib/CodeGen/CGOpenMPRuntime.h
  lib/CodeGen/CGStmtOpenMP.cpp
  lib/CodeGen/CodeGenFunction.h
  test/OpenMP/capturing_in_templates.cpp
  test/OpenMP/declare_mapper_codegen.cpp
  test/OpenMP/declare_target_link_codegen.cpp
  test/OpenMP/target_is_device_ptr_codegen.cpp

Index: test/OpenMP/target_is_device_ptr_codegen.cpp
===
--- test/OpenMP/target_is_device_ptr_codegen.cpp
+++ test/OpenMP/target_is_device_ptr_codegen.cpp
@@ -49,7 +49,7 @@
   float *l;
   T *t;
 
-  // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES00]]{{.+}}, {{.+}}[[TYPES00]]{{.+}})
+  // CK1-DAG: call i32 @__tgt_target_mapper(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES00]]{{.+}}, {{.+}}[[TYPES00]]{{.+}})
   // CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -66,7 +66,7 @@
 ++g;
   }
 
-  // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES01]]{{.+}}, {{.+}}[[TYPES01]]{{.+}})
+  // CK1-DAG: call i32 @__tgt_target_mapper(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES01]]{{.+}}, {{.+}}[[TYPES01]]{{.+}})
   // CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -83,7 +83,7 @@
 ++l;
   }
 
-  // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES02]]{{.+}}, {{.+}}[[TYPES02]]{{.+}})
+  // CK1-DAG: call i32 @__tgt_target_mapper(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES02]]{{.+}}, {{.+}}[[TYPES02]]{{.+}})
   // CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -100,7 +100,7 @@
 ++t;
   }
 
-  // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES03]]{{.+}}, {{.+}}[[TYPES03]]{{.+}})
+  // CK1-DAG: call i32 @__tgt_target_mapper(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES03]]{{.+}}, {{.+}}[[TYPES03]]{{.+}})
   // CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -118,7 +118,7 @@
 ++lr;
   }
 
-  // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES04]]{{.+}}, {{.+}}[[TYPES04]]{{.+}})
+  // CK1-DAG: call i32 @__tgt_target_mapper(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES04]]{{.+}}, {{.+}}[[TYPES04]]{{.+}})
   // CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -136,7 +136,7 @@
 ++tr;
   }
 
-  // CK1-DAG: call i32 @__tgt_target(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES05]]{{.+}}, {{.+}}[[TYPES05]]{{.+}})
+  // CK1-DAG: call i32 @__tgt_target_mapper(i64 {{.+}}, i8* {{.+}}, i32 1, i8** [[BPGEP:%[0-9]+]], i8** [[PGEP:%[0-9]+]], {{.+}}[[SIZES05]]{{.+}}, {{.+}}[[TYPES05]]{{.+}})
   // CK1-DAG: [[BPGEP]] = getelementptr inbounds {{.+}}[[BPS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[PGEP]] = getelementptr inbounds {{.+}}[[PS:%[^,]+]], i32 0, i32 0
   // CK1-DAG: [[BP1:%.+]] = getelementptr inbounds {{.+}}[[BPS]], i32 0, i32 0
@@ -154,7 +154,7 @@
 ++tr;
   }
 
-  // CK1-DAG: call i32 @__tgt_target(i64 {{

[PATCH] D67826: [clangd] A helper to find explicit references and their names

2019-09-20 Thread Kadir Cetinkaya via Phabricator via cfe-commits
kadircet added a comment.

Thanks this mostly LG, but I think we need some tests feel free to copy the 
ones in D66647  as a start point. But I 
believe coverage for this one is bigger, as this tries to figure-out all 
references, whereas the define-inline patch only cares about references to 
non-local decls in contexts that can have a nested name specifier.




Comment at: clang-tools-extra/clangd/FindTarget.cpp:369
+llvm::SmallVector
+explicitReferenceTargets(ast_type_traits::DynTypedNode N,
+ DeclRelationSet Mask = {}) {

could you add some comments on what it does



Comment at: clang-tools-extra/clangd/FindTarget.cpp:373
+   DeclRelation::TemplateInstantiation)) &&
+ "namedTarget handles templates on its own");
+  auto Decls = allTargetDecls(N);

what is `namedTarget` ?



Comment at: clang-tools-extra/clangd/FindTarget.cpp:376
+
+  // We prefer to return template instantiation, but fallback to template
+  // pattern if instantiation is not available.

can we simplify this by populating two vectors, Instantiations and Patterns, 
and then returning the patterns iff instantiations are empty?



Comment at: clang-tools-extra/clangd/FindTarget.cpp:381
+  llvm::find_if(Decls, [&](std::pair D) {
+if (D.second & ~Mask)
+  return false;

why do we discard aliases(specifically underlying decls) ? for example if we 
have `vector` I believe decl(`template<> std::vector`) will be marked 
with both TemplateInst and Underlying right ?



Comment at: clang-tools-extra/clangd/FindTarget.cpp:391
+  for (auto &D : Decls) {
+if (D.second & ~Mask)
+  continue;

same here for ignoring underlying decls



Comment at: clang-tools-extra/clangd/FindTarget.cpp:399
+Optional refInDecl(const Decl *D) {
+  struct Visitor : ConstDeclVisitor {
+llvm::Optional Ref;

these three(usingdirective,using,namespacealias) decls are the only ones that 
can have a nestednamespecifier.

Are we sure these are the only ones that can reference a decl? For example what 
about a `ConstructorDecl` with initializers referencing `FieldDecl`s, I believe 
this function should rather return multiple locations in such cases.



Comment at: clang-tools-extra/clangd/FindTarget.cpp:409
+void VisitUsingDecl(const UsingDecl *D) {
+  Ref = ReferenceLoc{D->getQualifierLoc(), D->getUsingLoc(),
+ explicitReferenceTargets(DynTypedNode::create(*D),

I think `getUsingLoc` will return the location for `using` keyword, not the 
name location. Maybe use `getLocation` ?



Comment at: clang-tools-extra/clangd/FindTarget.cpp:426
+
+Optional refInExpr(const Expr *E) {
+  struct Visitor : ConstStmtVisitor {

again I believe this list is non-exhaustive, e.g. designatedinitilaizers. and 
again this also needs to return a vector instead.



Comment at: clang-tools-extra/clangd/FindTarget.cpp:432
+  Ref = ReferenceLoc{
+  E->getQualifierLoc(), E->getNameInfo().getLoc(), {E->getDecl()}};
+}

I believe it is better to return `getFoundDecl` then `getDecl`, the former 
respects using declarations.



Comment at: clang-tools-extra/clangd/FindTarget.cpp:506
+
+llvm::Optional
+explicitReference(ast_type_traits::DynTypedNode N) {

can we move this below `ExplicitReferenceCollector` to prevent splitting anon 
namespace?



Comment at: clang-tools-extra/clangd/FindTarget.cpp:548
+  bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc L) {
+// ElaboratedTypeLoc will reports information for its inner type loc.
+// Otherwise we loose information about inner types loc's qualifier.

why not just traversenestednamespecifier and `visitNode(L)` instead of calling 
the base::traverse ?



Comment at: clang-tools-extra/clangd/FindTarget.cpp:570
+visitNode(DynTypedNode::create(L));
+// Inner type is missing information about its qualifier, skip it.
+if (auto TL = L.getTypeLoc())

why not just visitNode(L) and traverse(prefix(L)) instead of calling base?



Comment at: clang-tools-extra/clangd/FindTarget.cpp:581
+  return;
+// FIXME: this should be done by nodeReference.
+if (Ref->NameLoc.isInvalid() || Ref->NameLoc.isMacroID())

what is `nodeReference`?



Comment at: clang-tools-extra/clangd/FindTarget.cpp:594
+
+void findExplicitReferences(Stmt *S,
+llvm::function_ref Out) {

So this endpoint doesn't seem to have downsides above(not visiting all 
referenced decls) as it performs traversal through an extra ASTVisitor.

What is the point of expo

r372394 - [CUDA][HIP] Fix hostness of defaulted constructor

2019-09-20 Thread Yaxun Liu via cfe-commits
Author: yaxunl
Date: Fri Sep 20 07:28:09 2019
New Revision: 372394

URL: http://llvm.org/viewvc/llvm-project?rev=372394&view=rev
Log:
[CUDA][HIP] Fix hostness of defaulted constructor
Clang does not respect the explicit device host attributes of defaulted special 
members.
Also clang does not respect the hostness of special members determined by their
first declarations.
Clang also adds duplicate implicit device or host attributes in certain cases.
This patch fixes that.
Differential Revision: https://reviews.llvm.org/D67509

Added:
cfe/trunk/test/SemaCUDA/default-ctor.cu
Modified:
cfe/trunk/lib/Sema/SemaCUDA.cpp

Modified: cfe/trunk/lib/Sema/SemaCUDA.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCUDA.cpp?rev=372394&r1=372393&r2=372394&view=diff
==
--- cfe/trunk/lib/Sema/SemaCUDA.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCUDA.cpp Fri Sep 20 07:28:09 2019
@@ -267,6 +267,18 @@ bool Sema::inferCUDATargetForImplicitSpe
CXXMethodDecl *MemberDecl,
bool ConstRHS,
bool Diagnose) {
+  // If the defaulted special member is defined lexically outside of its
+  // owning class, or the special member already has explicit device or host
+  // attributes, do not infer.
+  bool InClass = MemberDecl->getLexicalParent() == MemberDecl->getParent();
+  bool HasH = MemberDecl->hasAttr();
+  bool HasD = MemberDecl->hasAttr();
+  bool HasExplicitAttr =
+  (HasD && !MemberDecl->getAttr()->isImplicit()) ||
+  (HasH && !MemberDecl->getAttr()->isImplicit());
+  if (!InClass || HasExplicitAttr)
+return false;
+
   llvm::Optional InferredTarget;
 
   // We're going to invoke special member lookup; mark that these special
@@ -371,21 +383,24 @@ bool Sema::inferCUDATargetForImplicitSpe
 }
   }
 
+
+  // If no target was inferred, mark this member as __host__ __device__;
+  // it's the least restrictive option that can be invoked from any target.
+  bool NeedsH = true, NeedsD = true;
   if (InferredTarget.hasValue()) {
-if (InferredTarget.getValue() == CFT_Device) {
-  MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context));
-} else if (InferredTarget.getValue() == CFT_Host) {
-  MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context));
-} else {
-  MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context));
-  MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context));
-}
-  } else {
-// If no target was inferred, mark this member as __host__ __device__;
-// it's the least restrictive option that can be invoked from any target.
+if (InferredTarget.getValue() == CFT_Device)
+  NeedsH = false;
+else if (InferredTarget.getValue() == CFT_Host)
+  NeedsD = false;
+  }
+
+  // We either setting attributes first time, or the inferred ones must match
+  // previously set ones.
+  assert(!(HasD || HasH) || (NeedsD == HasD && NeedsH == HasH));
+  if (NeedsD && !HasD)
 MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context));
+  if (NeedsH && !HasH)
 MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context));
-  }
 
   return false;
 }

Added: cfe/trunk/test/SemaCUDA/default-ctor.cu
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCUDA/default-ctor.cu?rev=372394&view=auto
==
--- cfe/trunk/test/SemaCUDA/default-ctor.cu (added)
+++ cfe/trunk/test/SemaCUDA/default-ctor.cu Fri Sep 20 07:28:09 2019
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only \
+// RUN:-fcuda-is-device -verify -verify-ignore-unexpected=note %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -fsyntax-only \
+// RUN:-verify -verify-ignore-unexpected=note %s
+
+#include "Inputs/cuda.h"
+
+struct In { In() = default; };
+struct InD { __device__ InD() = default; };
+struct InH { __host__ InH() = default; };
+struct InHD { __host__ __device__ InHD() = default; };
+
+struct Out { Out(); };
+struct OutD { __device__ OutD(); };
+struct OutH { __host__ OutH(); };
+struct OutHD { __host__ __device__ OutHD(); };
+
+Out::Out() = default;
+__device__ OutD::OutD() = default;
+__host__ OutH::OutH() = default;
+__host__ __device__ OutHD::OutHD() = default;
+
+__device__ void fd() {
+  In in;
+  InD ind;
+  InH inh; // expected-error{{no matching constructor for initialization of 
'InH'}}
+  InHD inhd;
+  Out out; // expected-error{{no matching constructor for initialization of 
'Out'}}
+  OutD outd;
+  OutH outh; // expected-error{{no matching constructor for initialization of 
'OutH'}}
+  OutHD outhd;
+}
+
+__host__ void fh() {
+  In in;
+  InD ind; // expected-error{{no matching constructor for initialization of 
'InD'}}
+  InH inh;
+  InHD inhd;
+  Out out;
+  OutD outd; // expected

[PATCH] D67509: [CUDA][HIP] Fix hostness of defaulted constructor

2019-09-20 Thread Yaxun Liu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL372394: [CUDA][HIP] Fix hostness of defaulted constructor 
(authored by yaxunl, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D67509?vs=220912&id=221029#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D67509

Files:
  cfe/trunk/lib/Sema/SemaCUDA.cpp
  cfe/trunk/test/SemaCUDA/default-ctor.cu

Index: cfe/trunk/lib/Sema/SemaCUDA.cpp
===
--- cfe/trunk/lib/Sema/SemaCUDA.cpp
+++ cfe/trunk/lib/Sema/SemaCUDA.cpp
@@ -267,6 +267,18 @@
CXXMethodDecl *MemberDecl,
bool ConstRHS,
bool Diagnose) {
+  // If the defaulted special member is defined lexically outside of its
+  // owning class, or the special member already has explicit device or host
+  // attributes, do not infer.
+  bool InClass = MemberDecl->getLexicalParent() == MemberDecl->getParent();
+  bool HasH = MemberDecl->hasAttr();
+  bool HasD = MemberDecl->hasAttr();
+  bool HasExplicitAttr =
+  (HasD && !MemberDecl->getAttr()->isImplicit()) ||
+  (HasH && !MemberDecl->getAttr()->isImplicit());
+  if (!InClass || HasExplicitAttr)
+return false;
+
   llvm::Optional InferredTarget;
 
   // We're going to invoke special member lookup; mark that these special
@@ -371,21 +383,24 @@
 }
   }
 
+
+  // If no target was inferred, mark this member as __host__ __device__;
+  // it's the least restrictive option that can be invoked from any target.
+  bool NeedsH = true, NeedsD = true;
   if (InferredTarget.hasValue()) {
-if (InferredTarget.getValue() == CFT_Device) {
-  MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context));
-} else if (InferredTarget.getValue() == CFT_Host) {
-  MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context));
-} else {
-  MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context));
-  MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context));
-}
-  } else {
-// If no target was inferred, mark this member as __host__ __device__;
-// it's the least restrictive option that can be invoked from any target.
+if (InferredTarget.getValue() == CFT_Device)
+  NeedsH = false;
+else if (InferredTarget.getValue() == CFT_Host)
+  NeedsD = false;
+  }
+
+  // We either setting attributes first time, or the inferred ones must match
+  // previously set ones.
+  assert(!(HasD || HasH) || (NeedsD == HasD && NeedsH == HasH));
+  if (NeedsD && !HasD)
 MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context));
+  if (NeedsH && !HasH)
 MemberDecl->addAttr(CUDAHostAttr::CreateImplicit(Context));
-  }
 
   return false;
 }
Index: cfe/trunk/test/SemaCUDA/default-ctor.cu
===
--- cfe/trunk/test/SemaCUDA/default-ctor.cu
+++ cfe/trunk/test/SemaCUDA/default-ctor.cu
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++11 -triple nvptx64-nvidia-cuda -fsyntax-only \
+// RUN:-fcuda-is-device -verify -verify-ignore-unexpected=note %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-linux-gnu -fsyntax-only \
+// RUN:-verify -verify-ignore-unexpected=note %s
+
+#include "Inputs/cuda.h"
+
+struct In { In() = default; };
+struct InD { __device__ InD() = default; };
+struct InH { __host__ InH() = default; };
+struct InHD { __host__ __device__ InHD() = default; };
+
+struct Out { Out(); };
+struct OutD { __device__ OutD(); };
+struct OutH { __host__ OutH(); };
+struct OutHD { __host__ __device__ OutHD(); };
+
+Out::Out() = default;
+__device__ OutD::OutD() = default;
+__host__ OutH::OutH() = default;
+__host__ __device__ OutHD::OutHD() = default;
+
+__device__ void fd() {
+  In in;
+  InD ind;
+  InH inh; // expected-error{{no matching constructor for initialization of 'InH'}}
+  InHD inhd;
+  Out out; // expected-error{{no matching constructor for initialization of 'Out'}}
+  OutD outd;
+  OutH outh; // expected-error{{no matching constructor for initialization of 'OutH'}}
+  OutHD outhd;
+}
+
+__host__ void fh() {
+  In in;
+  InD ind; // expected-error{{no matching constructor for initialization of 'InD'}}
+  InH inh;
+  InHD inhd;
+  Out out;
+  OutD outd; // expected-error{{no matching constructor for initialization of 'OutD'}}
+  OutH outh;
+  OutHD outhd;
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53768: Add VerboseOutputStream to CompilerInstance

2019-09-20 Thread Scott Linder via Phabricator via cfe-commits
scott.linder marked an inline comment as done.
scott.linder added inline comments.



Comment at: include/clang/Frontend/CompilerInstance.h:362-363
+  /// If not set, this stream defaults to \c llvm::errs().
+  void setVerboseOutputStream(raw_ostream &Value,
+  bool OwnsOutputStream = false);
+

dblaikie wrote:
> Two functions - one that takes a raw_ostream& and another that takes a 
> unique_ptr?
Do both overloads transfer ownership? Are the "standard" streams like 
`llvm::outs()` OK to free?


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

https://reviews.llvm.org/D53768



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67632: [libTooling] Introduce new library of source-code builders.

2019-09-20 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel updated this revision to Diff 221041.
ymandel added a comment.

address comments and some general cleanup


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67632

Files:
  clang/include/clang/Tooling/Refactoring/SourceCodeBuilders.h
  clang/lib/Tooling/Refactoring/CMakeLists.txt
  clang/lib/Tooling/Refactoring/SourceCodeBuilders.cpp
  clang/unittests/Tooling/CMakeLists.txt
  clang/unittests/Tooling/SourceCodeBuildersTest.cpp

Index: clang/unittests/Tooling/SourceCodeBuildersTest.cpp
===
--- /dev/null
+++ clang/unittests/Tooling/SourceCodeBuildersTest.cpp
@@ -0,0 +1,227 @@
+//===- unittest/Tooling/SourceCodeBuildersTest.cpp ===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "clang/Tooling/Refactoring/SourceCodeBuilders.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace tooling;
+using namespace ast_matchers;
+
+namespace {
+using MatchResult = MatchFinder::MatchResult;
+
+// Create a valid translation unit from a statement.
+static std::string wrapSnippet(StringRef StatementCode) {
+  return ("struct S { S(); S(int); int field; };\n"
+  "S operator+(const S &a, const S &b);\n"
+  "auto test_snippet = []{" +
+  StatementCode + "};")
+  .str();
+}
+
+static DeclarationMatcher wrapMatcher(const StatementMatcher &Matcher) {
+  return varDecl(hasName("test_snippet"),
+ hasDescendant(compoundStmt(hasAnySubstatement(Matcher;
+}
+
+struct TestMatch {
+  // The AST unit from which `result` is built. We bundle it because it backs
+  // the result. Users are not expected to access it.
+  std::unique_ptr AstUnit;
+  // The result to use in the test. References `ast_unit`.
+  MatchResult Result;
+};
+
+// Matches `Matcher` against the statement `StatementCode` and returns the
+// result. Handles putting the statement inside a function and modifying the
+// matcher correspondingly. `Matcher` should match one of the statements in
+// `StatementCode` exactly -- that is, produce exactly one match. However,
+// `StatementCode` may contain other statements not described by `Matcher`.
+static llvm::Optional matchStmt(StringRef StatementCode,
+   StatementMatcher Matcher) {
+  auto AstUnit = buildASTFromCode(wrapSnippet(StatementCode));
+  if (AstUnit == nullptr) {
+ADD_FAILURE() << "AST construction failed";
+return llvm::None;
+  }
+  ASTContext &Context = AstUnit->getASTContext();
+  auto Matches = ast_matchers::match(wrapMatcher(Matcher), Context);
+  // We expect a single, exact match for the statement.
+  if (Matches.size() != 1) {
+ADD_FAILURE() << "Wrong number of matches: " << Matches.size();
+return llvm::None;
+  }
+  return TestMatch{std::move(AstUnit), MatchResult(Matches[0], &Context)};
+}
+
+static void testPredicate(bool (*Pred)(const Expr &), StringRef Snippet,
+  bool Expected) {
+  auto StmtMatch = matchStmt(Snippet, expr().bind("expr"));
+  ASSERT_TRUE(StmtMatch) << "Snippet: " << Snippet;
+  EXPECT_EQ(Expected, Pred(*StmtMatch->Result.Nodes.getNodeAs("expr")))
+  << "Snippet: " << Snippet;
+}
+
+// Tests the predicate on the call argument, assuming `Snippet` is a function
+// call.
+static void testPredicateOnArg(bool (*Pred)(const Expr &), StringRef Snippet,
+   bool Expected) {
+  auto StmtMatch = matchStmt(
+  Snippet, expr(ignoringImplicit(callExpr(hasArgument(
+   0, ignoringElidableConstructorCall(expr().bind("arg")));
+  ASSERT_TRUE(StmtMatch) << "Snippet: " << Snippet;
+  EXPECT_EQ(Expected, Pred(*StmtMatch->Result.Nodes.getNodeAs("arg")))
+  << "Snippet: " << Snippet;
+}
+
+TEST(SourceCodeBuildersTest, needParensAfterUnaryOperator) {
+  testPredicate(needParensAfterUnaryOperator, "3 + 5;", true);
+  testPredicate(needParensAfterUnaryOperator, "true ? 3 : 5;", true);
+  testPredicate(needParensAfterUnaryOperator, "S(3) + S(5);", true);
+
+  testPredicate(needParensAfterUnaryOperator, "int x; x;", false);
+  testPredicate(needParensAfterUnaryOperator, "int(3.0);", false);
+  testPredicate(needParensAfterUnaryOperator, "void f(); f();", false);
+  testPredicate(needParensAfterUnaryOperator, "int a[3]; a[0];", false);
+  testPredicate(needParensAfterUnaryOperator, "S x; x.field;", false);
+  testPredicate(needParensAfterUnaryOperator, "int x = 1; --x;", false);
+  testPredicate(needParensAfterUnaryOperator, "int x =

[PATCH] D67837: [CUDA][HIP] Fix assertion in Sema::markKnownEmitted with -fopenmp

2019-09-20 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl created this revision.
yaxunl added reviewers: tra, rjmccall.
Herald added a subscriber: guansong.
Herald added a reviewer: jdoerfert.
Herald added a project: clang.

CUDA/HIP program may be compiled with -fopenmp. In this case, -fopenmp is only 
passed to host compilation
to take advantages of multi-threads computation.

CUDA/HIP and OpenMP both use Sema::DeviceCallGraph to store functions to be 
analyzed and remove them
once they decide the function is sure to be emitted. CUDA/HIP and OpenMP have 
different functions to determine
of a function is sure to be emitted.

This patch fixes an assertion which happens when CUDA/HIP is compiled with 
-fopenmp.


Repository:
  rC Clang

https://reviews.llvm.org/D67837

Files:
  lib/Sema/Sema.cpp
  test/SemaCUDA/openmp-static-func.cu


Index: test/SemaCUDA/openmp-static-func.cu
===
--- /dev/null
+++ test/SemaCUDA/openmp-static-func.cu
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
+// RUN:-verify -fopenmp %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
+// RUN:-verify -fopenmp -x hip %s
+// expected-no-diagnostics
+
+// Tests there is no assertion in Sema::markKnownEmitted when fopenmp is used
+// with CUDA/HIP host compilation.
+
+static void f() {}
+
+static void g() { f(); }
+
+static void h() { g(); }
Index: lib/Sema/Sema.cpp
===
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -1503,7 +1503,12 @@
 const llvm::function_ref IsKnownEmitted) {
   // Nothing to do if we already know that FD is emitted.
   if (IsKnownEmitted(S, OrigCallee)) {
-assert(!S.DeviceCallGraph.count(OrigCallee));
+// CUDA/HIP and OpenMP both put functions in DeviceCallGraph. A function
+// not sure to be emitted by one language may be found sure to be emitted
+// by another language. In this case, just erase it from DeviceCallGraph.
+auto Loc = S.DeviceCallGraph.find(OrigCallee);
+if (Loc != S.DeviceCallGraph.end())
+  S.DeviceCallGraph.erase(Loc);
 return;
   }
 


Index: test/SemaCUDA/openmp-static-func.cu
===
--- /dev/null
+++ test/SemaCUDA/openmp-static-func.cu
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
+// RUN:-verify -fopenmp %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
+// RUN:-verify -fopenmp -x hip %s
+// expected-no-diagnostics
+
+// Tests there is no assertion in Sema::markKnownEmitted when fopenmp is used
+// with CUDA/HIP host compilation.
+
+static void f() {}
+
+static void g() { f(); }
+
+static void h() { g(); }
Index: lib/Sema/Sema.cpp
===
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -1503,7 +1503,12 @@
 const llvm::function_ref IsKnownEmitted) {
   // Nothing to do if we already know that FD is emitted.
   if (IsKnownEmitted(S, OrigCallee)) {
-assert(!S.DeviceCallGraph.count(OrigCallee));
+// CUDA/HIP and OpenMP both put functions in DeviceCallGraph. A function
+// not sure to be emitted by one language may be found sure to be emitted
+// by another language. In this case, just erase it from DeviceCallGraph.
+auto Loc = S.DeviceCallGraph.find(OrigCallee);
+if (Loc != S.DeviceCallGraph.end())
+  S.DeviceCallGraph.erase(Loc);
 return;
   }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[libunwind] r372407 - Unwind: prevent unw_get_proc_info from returning stale data

2019-09-20 Thread Saleem Abdulrasool via cfe-commits
Author: compnerd
Date: Fri Sep 20 08:53:42 2019
New Revision: 372407

URL: http://llvm.org/viewvc/llvm-project?rev=372407&view=rev
Log:
Unwind: prevent unw_get_proc_info from returning stale data

If unwind info is not available at the current IP, unw_get_proc_info should
return a zero-filled structure rather than the info of the previous IP.

This change also makes unw_get_proc_info return UNW_ENOINFO instead of
UNW_ESUCCESS.

Patch by Amanieu d'Antras!

Modified:
libunwind/trunk/src/UnwindCursor.hpp
libunwind/trunk/test/libunwind_01.pass.cpp

Modified: libunwind/trunk/src/UnwindCursor.hpp
URL: 
http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/UnwindCursor.hpp?rev=372407&r1=372406&r2=372407&view=diff
==
--- libunwind/trunk/src/UnwindCursor.hpp (original)
+++ libunwind/trunk/src/UnwindCursor.hpp Fri Sep 20 08:53:42 2019
@@ -1991,7 +1991,10 @@ int UnwindCursor::step() {
 
 template 
 void UnwindCursor::getInfo(unw_proc_info_t *info) {
-  *info = _info;
+  if (_unwindInfoMissing)
+memset(info, 0, sizeof(*info));
+  else
+*info = _info;
 }
 
 template 

Modified: libunwind/trunk/test/libunwind_01.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libunwind/trunk/test/libunwind_01.pass.cpp?rev=372407&r1=372406&r2=372407&view=diff
==
--- libunwind/trunk/test/libunwind_01.pass.cpp (original)
+++ libunwind/trunk/test/libunwind_01.pass.cpp Fri Sep 20 08:53:42 2019
@@ -35,8 +35,29 @@ void test3(int i, int j, int k) {
   test2(j, k);
 }
 
+void test_no_info() {
+  unw_context_t context;
+  unw_getcontext(&context);
+
+  unw_cursor_t cursor;
+  unw_init_local(&cursor, &context);
+
+  unw_proc_info_t info;
+  int ret = unw_get_proc_info(&cursor, &info);
+  if (ret != UNW_ESUCCESS)
+abort();
+
+  // Set the IP to an address clearly outside any function.
+  unw_set_reg(&cursor, UNW_REG_IP, (unw_word_t)&context);
+
+  ret = unw_get_proc_info(&cursor, &info);
+  if (ret != UNW_ENOINFO)
+abort();
+}
+
 int main() {
   test1(1);
   test2(1, 2);
   test3(1, 2, 3);
+  test_no_info();
 }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D51372: FENV_ACCESS support for libm-style constrained intrinsics

2019-09-20 Thread Kevin P. Neal via Phabricator via cfe-commits
kpn abandoned this revision.
kpn added a comment.

I believe Serge Pavlov has demonstrated a better way to do this.


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

https://reviews.llvm.org/D51372



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52839: Inform AST's UnaryOperator of FENV_ACCESS

2019-09-20 Thread Kevin P. Neal via Phabricator via cfe-commits
kpn abandoned this revision.
kpn added a comment.

I believe Serge Pavlov has demonstrated a better way to do this.


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

https://reviews.llvm.org/D52839



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67621: [libTooling] Add `ifBound`, `elseBranch` RangeSelector combinators.

2019-09-20 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel updated this revision to Diff 221050.
ymandel marked 2 inline comments as done.
ymandel added a comment.

reordered decls


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67621

Files:
  clang/include/clang/Tooling/Refactoring/RangeSelector.h
  clang/lib/Tooling/Refactoring/RangeSelector.cpp
  clang/unittests/Tooling/RangeSelectorTest.cpp

Index: clang/unittests/Tooling/RangeSelectorTest.cpp
===
--- clang/unittests/Tooling/RangeSelectorTest.cpp
+++ clang/unittests/Tooling/RangeSelectorTest.cpp
@@ -520,6 +520,60 @@
Failed(withTypeErrorMessage("stmt")));
 }
 
+TEST(RangeSelectorTest, IfBoundOpBound) {
+  StringRef Code = R"cc(
+int f() {
+  return 3 + 5;
+}
+  )cc";
+  StringRef ID = "id", Op = "op";
+  TestMatch Match =
+  matchCode(Code, binaryOperator(hasLHS(expr().bind(ID))).bind(Op));
+  EXPECT_THAT_EXPECTED(select(ifBound(ID, node(ID), node(Op)), Match),
+   HasValue("3"));
+}
+
+TEST(RangeSelectorTest, IfBoundOpUnbound) {
+  StringRef Code = R"cc(
+int f() {
+  return 3 + 5;
+}
+  )cc";
+  StringRef ID = "id", Op = "op";
+  TestMatch Match = matchCode(Code, binaryOperator().bind(Op));
+  EXPECT_THAT_EXPECTED(select(ifBound(ID, node(ID), node(Op)), Match),
+   HasValue("3 + 5"));
+}
+
+TEST(RangeSelectorTest, ElseBranchOpSingleStatement) {
+  StringRef Code = R"cc(
+int f() {
+  int x = 0;
+  if (true) x = 3;
+  else x = 4;
+  return x + 5;
+}
+  )cc";
+  StringRef ID = "id";
+  TestMatch Match = matchCode(Code, ifStmt().bind(ID));
+  EXPECT_THAT_EXPECTED(select(elseBranch(ID), Match), HasValue("else x = 4;"));
+}
+
+TEST(RangeSelectorTest, ElseBranchOpCompoundStatement) {
+  StringRef Code = R"cc(
+int f() {
+  int x = 0;
+  if (true) x = 3;
+  else { x = 4; }
+  return x + 5;
+}
+  )cc";
+  StringRef ID = "id";
+  TestMatch Match = matchCode(Code, ifStmt().bind(ID));
+  EXPECT_THAT_EXPECTED(select(elseBranch(ID), Match),
+   HasValue("else { x = 4; }"));
+}
+
 // Tests case where the matched node is the complete expanded text.
 TEST(RangeSelectorTest, ExpansionOp) {
   StringRef Code = R"cc(
Index: clang/lib/Tooling/Refactoring/RangeSelector.cpp
===
--- clang/lib/Tooling/Refactoring/RangeSelector.cpp
+++ clang/lib/Tooling/Refactoring/RangeSelector.cpp
@@ -219,6 +219,9 @@
 }
 
 namespace {
+// FIXME: make this available in the public API for users to easily create their
+// own selectors.
+
 // Creates a selector from a range-selection function \p Func, which selects a
 // range that is relative to a bound node id.  \c T is the node type expected by
 // \p Func.
@@ -286,6 +289,19 @@
   return RelativeSelector(std::move(ID));
 }
 
+namespace {
+// Returns the range of the else branch, including the `else` keyword.
+CharSourceRange getElseRange(const MatchResult &Result, const IfStmt &S) {
+  return maybeExtendRange(
+  CharSourceRange::getTokenRange(S.getElseLoc(), S.getEndLoc()),
+  tok::TokenKind::semi, *Result.Context);
+}
+} // namespace
+
+RangeSelector tooling::elseBranch(std::string ID) {
+  return RelativeSelector(std::move(ID));
+}
+
 RangeSelector tooling::expansion(RangeSelector S) {
   return [S](const MatchResult &Result) -> Expected {
 Expected SRange = S(Result);
@@ -294,3 +310,11 @@
 return Result.SourceManager->getExpansionRange(*SRange);
   };
 }
+
+RangeSelector tooling::ifBound(std::string ID, RangeSelector TrueSelector,
+   RangeSelector FalseSelector) {
+  return [=](const MatchResult &Result) {
+auto &Map = Result.Nodes.getMap();
+return (Map.find(ID) != Map.end() ? TrueSelector : FalseSelector)(Result);
+  };
+}
Index: clang/include/clang/Tooling/Refactoring/RangeSelector.h
===
--- clang/include/clang/Tooling/Refactoring/RangeSelector.h
+++ clang/include/clang/Tooling/Refactoring/RangeSelector.h
@@ -79,10 +79,19 @@
 // (all source between the braces).
 RangeSelector initListElements(std::string ID);
 
+/// Given an \IfStmt (bound to \p ID), selects the range of the else branch,
+/// starting from the \c else keyword.
+RangeSelector elseBranch(std::string ID);
+
 /// Selects the range from which `S` was expanded (possibly along with other
 /// source), if `S` is an expansion, and `S` itself, otherwise.  Corresponds to
 /// `SourceManager::getExpansionRange`.
 RangeSelector expansion(RangeSelector S);
+
+/// Chooses between the two selectors, based on whether \p ID is bound in the
+/// match.
+RangeSelector ifBound(std::string ID, RangeSelector TrueSelector,
+  RangeSelector FalseSelector);
 } // namespace tooling
 } // namespace clang
 
_

[PATCH] D67621: [libTooling] Add `ifBound`, `elseBranch` RangeSelector combinators.

2019-09-20 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel added inline comments.



Comment at: clang/lib/Tooling/Refactoring/RangeSelector.cpp:320
+  };
+}

gribozavr wrote:
> May I ask to keep the implementation order consistent with the header file?
Moved the decl in the header to match the ordering in the implementation, which 
results in a better grouping (in terms of the signature and semantics of the 
combinators).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67621



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67621: [libTooling] Add `ifBound`, `elseBranch` RangeSelector combinators.

2019-09-20 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel updated this revision to Diff 221052.
ymandel added a comment.

reordered tests to match as well.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67621

Files:
  clang/include/clang/Tooling/Refactoring/RangeSelector.h
  clang/lib/Tooling/Refactoring/RangeSelector.cpp
  clang/unittests/Tooling/RangeSelectorTest.cpp

Index: clang/unittests/Tooling/RangeSelectorTest.cpp
===
--- clang/unittests/Tooling/RangeSelectorTest.cpp
+++ clang/unittests/Tooling/RangeSelectorTest.cpp
@@ -520,6 +520,35 @@
Failed(withTypeErrorMessage("stmt")));
 }
 
+TEST(RangeSelectorTest, ElseBranchOpSingleStatement) {
+  StringRef Code = R"cc(
+int f() {
+  int x = 0;
+  if (true) x = 3;
+  else x = 4;
+  return x + 5;
+}
+  )cc";
+  StringRef ID = "id";
+  TestMatch Match = matchCode(Code, ifStmt().bind(ID));
+  EXPECT_THAT_EXPECTED(select(elseBranch(ID), Match), HasValue("else x = 4;"));
+}
+
+TEST(RangeSelectorTest, ElseBranchOpCompoundStatement) {
+  StringRef Code = R"cc(
+int f() {
+  int x = 0;
+  if (true) x = 3;
+  else { x = 4; }
+  return x + 5;
+}
+  )cc";
+  StringRef ID = "id";
+  TestMatch Match = matchCode(Code, ifStmt().bind(ID));
+  EXPECT_THAT_EXPECTED(select(elseBranch(ID), Match),
+   HasValue("else { x = 4; }"));
+}
+
 // Tests case where the matched node is the complete expanded text.
 TEST(RangeSelectorTest, ExpansionOp) {
   StringRef Code = R"cc(
@@ -546,4 +575,29 @@
HasValue("BADDECL(x * x)"));
 }
 
+TEST(RangeSelectorTest, IfBoundOpBound) {
+  StringRef Code = R"cc(
+int f() {
+  return 3 + 5;
+}
+  )cc";
+  StringRef ID = "id", Op = "op";
+  TestMatch Match =
+  matchCode(Code, binaryOperator(hasLHS(expr().bind(ID))).bind(Op));
+  EXPECT_THAT_EXPECTED(select(ifBound(ID, node(ID), node(Op)), Match),
+   HasValue("3"));
+}
+
+TEST(RangeSelectorTest, IfBoundOpUnbound) {
+  StringRef Code = R"cc(
+int f() {
+  return 3 + 5;
+}
+  )cc";
+  StringRef ID = "id", Op = "op";
+  TestMatch Match = matchCode(Code, binaryOperator().bind(Op));
+  EXPECT_THAT_EXPECTED(select(ifBound(ID, node(ID), node(Op)), Match),
+   HasValue("3 + 5"));
+}
+
 } // namespace
Index: clang/lib/Tooling/Refactoring/RangeSelector.cpp
===
--- clang/lib/Tooling/Refactoring/RangeSelector.cpp
+++ clang/lib/Tooling/Refactoring/RangeSelector.cpp
@@ -219,6 +219,9 @@
 }
 
 namespace {
+// FIXME: make this available in the public API for users to easily create their
+// own selectors.
+
 // Creates a selector from a range-selection function \p Func, which selects a
 // range that is relative to a bound node id.  \c T is the node type expected by
 // \p Func.
@@ -286,6 +289,19 @@
   return RelativeSelector(std::move(ID));
 }
 
+namespace {
+// Returns the range of the else branch, including the `else` keyword.
+CharSourceRange getElseRange(const MatchResult &Result, const IfStmt &S) {
+  return maybeExtendRange(
+  CharSourceRange::getTokenRange(S.getElseLoc(), S.getEndLoc()),
+  tok::TokenKind::semi, *Result.Context);
+}
+} // namespace
+
+RangeSelector tooling::elseBranch(std::string ID) {
+  return RelativeSelector(std::move(ID));
+}
+
 RangeSelector tooling::expansion(RangeSelector S) {
   return [S](const MatchResult &Result) -> Expected {
 Expected SRange = S(Result);
@@ -294,3 +310,11 @@
 return Result.SourceManager->getExpansionRange(*SRange);
   };
 }
+
+RangeSelector tooling::ifBound(std::string ID, RangeSelector TrueSelector,
+   RangeSelector FalseSelector) {
+  return [=](const MatchResult &Result) {
+auto &Map = Result.Nodes.getMap();
+return (Map.find(ID) != Map.end() ? TrueSelector : FalseSelector)(Result);
+  };
+}
Index: clang/include/clang/Tooling/Refactoring/RangeSelector.h
===
--- clang/include/clang/Tooling/Refactoring/RangeSelector.h
+++ clang/include/clang/Tooling/Refactoring/RangeSelector.h
@@ -79,10 +79,19 @@
 // (all source between the braces).
 RangeSelector initListElements(std::string ID);
 
+/// Given an \IfStmt (bound to \p ID), selects the range of the else branch,
+/// starting from the \c else keyword.
+RangeSelector elseBranch(std::string ID);
+
 /// Selects the range from which `S` was expanded (possibly along with other
 /// source), if `S` is an expansion, and `S` itself, otherwise.  Corresponds to
 /// `SourceManager::getExpansionRange`.
 RangeSelector expansion(RangeSelector S);
+
+/// Chooses between the two selectors, based on whether \p ID is bound in the
+/// match.
+RangeSelector ifBound(std::string ID, RangeSelector TrueSelector,
+  RangeSelector FalseSelector);
 } // namespac

[PATCH] D67837: [CUDA][HIP] Fix assertion in Sema::markKnownEmitted with -fopenmp

2019-09-20 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: lib/Sema/Sema.cpp:1511
+if (Loc != S.DeviceCallGraph.end())
+  S.DeviceCallGraph.erase(Loc);
 return;

There's an overload of `DenseMap::erase` that just takes a key value, so this 
whole thing can be `S.DeviceCallGraph.erase(OrigCallee);`.

Why do we need to erase the entry instead of re-using it?  If the call graphs 
are different for the two use-cases, is that conflict a problem for other 
reasons?


Repository:
  rC Clang

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

https://reviews.llvm.org/D67837



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32435: clang-cl: Add support for /permissive-

2019-09-20 Thread Trass3r via Phabricator via cfe-commits
Trass3r added a comment.

Has this ever gotten anywhere?
I think the correct mapping would be something like -fno-ms-compatibility 
-fno-delayed-template-parsing, not sure about -fms-volatile -fms-extensions.


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

https://reviews.llvm.org/D32435



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67719: [clang] [Basic] Enable __has_feature(leak_sanitizer)

2019-09-20 Thread Kamil Rytarowski via Phabricator via cfe-commits
krytarowski added a comment.

Looks good to me but I will leave the final decision to someone else.


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

https://reviews.llvm.org/D67719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372410 - [libTooling] Add `ifBound`, `elseBranch` RangeSelector combinators.

2019-09-20 Thread Yitzhak Mandelbaum via cfe-commits
Author: ymandel
Date: Fri Sep 20 10:11:03 2019
New Revision: 372410

URL: http://llvm.org/viewvc/llvm-project?rev=372410&view=rev
Log:
[libTooling] Add `ifBound`, `elseBranch` RangeSelector combinators.

Summary:
Adds two new combinators and corresponding tests to the RangeSelector library.
* `ifBound` -- conditional evaluation of range-selectors, based on whether a
   given node id is bound in the match.
* `elseBranch` -- selects the source range of the else and its statement.

Reviewers: gribozavr

Subscribers: cfe-commits

Tags: #clang

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

Modified:
cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp

Modified: cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h?rev=372410&r1=372409&r2=372410&view=diff
==
--- cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h Fri Sep 20 
10:11:03 2019
@@ -79,10 +79,19 @@ RangeSelector statements(std::string ID)
 // (all source between the braces).
 RangeSelector initListElements(std::string ID);
 
+/// Given an \IfStmt (bound to \p ID), selects the range of the else branch,
+/// starting from the \c else keyword.
+RangeSelector elseBranch(std::string ID);
+
 /// Selects the range from which `S` was expanded (possibly along with other
 /// source), if `S` is an expansion, and `S` itself, otherwise.  Corresponds to
 /// `SourceManager::getExpansionRange`.
 RangeSelector expansion(RangeSelector S);
+
+/// Chooses between the two selectors, based on whether \p ID is bound in the
+/// match.
+RangeSelector ifBound(std::string ID, RangeSelector TrueSelector,
+  RangeSelector FalseSelector);
 } // namespace tooling
 } // namespace clang
 

Modified: cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp?rev=372410&r1=372409&r2=372410&view=diff
==
--- cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp Fri Sep 20 10:11:03 2019
@@ -219,6 +219,9 @@ RangeSelector tooling::name(std::string
 }
 
 namespace {
+// FIXME: make this available in the public API for users to easily create 
their
+// own selectors.
+
 // Creates a selector from a range-selection function \p Func, which selects a
 // range that is relative to a bound node id.  \c T is the node type expected 
by
 // \p Func.
@@ -286,6 +289,19 @@ RangeSelector tooling::initListElements(
   return RelativeSelector(std::move(ID));
 }
 
+namespace {
+// Returns the range of the else branch, including the `else` keyword.
+CharSourceRange getElseRange(const MatchResult &Result, const IfStmt &S) {
+  return maybeExtendRange(
+  CharSourceRange::getTokenRange(S.getElseLoc(), S.getEndLoc()),
+  tok::TokenKind::semi, *Result.Context);
+}
+} // namespace
+
+RangeSelector tooling::elseBranch(std::string ID) {
+  return RelativeSelector(std::move(ID));
+}
+
 RangeSelector tooling::expansion(RangeSelector S) {
   return [S](const MatchResult &Result) -> Expected {
 Expected SRange = S(Result);
@@ -294,3 +310,11 @@ RangeSelector tooling::expansion(RangeSe
 return Result.SourceManager->getExpansionRange(*SRange);
   };
 }
+
+RangeSelector tooling::ifBound(std::string ID, RangeSelector TrueSelector,
+   RangeSelector FalseSelector) {
+  return [=](const MatchResult &Result) {
+auto &Map = Result.Nodes.getMap();
+return (Map.find(ID) != Map.end() ? TrueSelector : FalseSelector)(Result);
+  };
+}

Modified: cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp?rev=372410&r1=372409&r2=372410&view=diff
==
--- cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp Fri Sep 20 10:11:03 2019
@@ -520,6 +520,35 @@ TEST(RangeSelectorTest, ElementsOpErrors
Failed(withTypeErrorMessage("stmt")));
 }
 
+TEST(RangeSelectorTest, ElseBranchOpSingleStatement) {
+  StringRef Code = R"cc(
+int f() {
+  int x = 0;
+  if (true) x = 3;
+  else x = 4;
+  return x + 5;
+}
+  )cc";
+  StringRef ID = "id";
+  TestMatch Match = matchCode(Code, ifStmt().bind(ID));
+  EXPECT_THAT_EXPECTED(select(elseBranch(ID), Match), HasValue("else x = 4;"));
+}
+
+TEST(RangeSelectorTest, ElseBranchOpCompoundStatement) {
+  StringRef Code = R"cc(
+int f() {
+  int x = 0;
+   

[PATCH] D67621: [libTooling] Add `ifBound`, `elseBranch` RangeSelector combinators.

2019-09-20 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL372410: [libTooling] Add `ifBound`, `elseBranch` 
RangeSelector combinators. (authored by ymandel, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D67621?vs=221052&id=221056#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D67621

Files:
  cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
  cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
  cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp

Index: cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
===
--- cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
+++ cfe/trunk/unittests/Tooling/RangeSelectorTest.cpp
@@ -520,6 +520,35 @@
Failed(withTypeErrorMessage("stmt")));
 }
 
+TEST(RangeSelectorTest, ElseBranchOpSingleStatement) {
+  StringRef Code = R"cc(
+int f() {
+  int x = 0;
+  if (true) x = 3;
+  else x = 4;
+  return x + 5;
+}
+  )cc";
+  StringRef ID = "id";
+  TestMatch Match = matchCode(Code, ifStmt().bind(ID));
+  EXPECT_THAT_EXPECTED(select(elseBranch(ID), Match), HasValue("else x = 4;"));
+}
+
+TEST(RangeSelectorTest, ElseBranchOpCompoundStatement) {
+  StringRef Code = R"cc(
+int f() {
+  int x = 0;
+  if (true) x = 3;
+  else { x = 4; }
+  return x + 5;
+}
+  )cc";
+  StringRef ID = "id";
+  TestMatch Match = matchCode(Code, ifStmt().bind(ID));
+  EXPECT_THAT_EXPECTED(select(elseBranch(ID), Match),
+   HasValue("else { x = 4; }"));
+}
+
 // Tests case where the matched node is the complete expanded text.
 TEST(RangeSelectorTest, ExpansionOp) {
   StringRef Code = R"cc(
@@ -546,4 +575,29 @@
HasValue("BADDECL(x * x)"));
 }
 
+TEST(RangeSelectorTest, IfBoundOpBound) {
+  StringRef Code = R"cc(
+int f() {
+  return 3 + 5;
+}
+  )cc";
+  StringRef ID = "id", Op = "op";
+  TestMatch Match =
+  matchCode(Code, binaryOperator(hasLHS(expr().bind(ID))).bind(Op));
+  EXPECT_THAT_EXPECTED(select(ifBound(ID, node(ID), node(Op)), Match),
+   HasValue("3"));
+}
+
+TEST(RangeSelectorTest, IfBoundOpUnbound) {
+  StringRef Code = R"cc(
+int f() {
+  return 3 + 5;
+}
+  )cc";
+  StringRef ID = "id", Op = "op";
+  TestMatch Match = matchCode(Code, binaryOperator().bind(Op));
+  EXPECT_THAT_EXPECTED(select(ifBound(ID, node(ID), node(Op)), Match),
+   HasValue("3 + 5"));
+}
+
 } // namespace
Index: cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
===
--- cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
+++ cfe/trunk/include/clang/Tooling/Refactoring/RangeSelector.h
@@ -79,10 +79,19 @@
 // (all source between the braces).
 RangeSelector initListElements(std::string ID);
 
+/// Given an \IfStmt (bound to \p ID), selects the range of the else branch,
+/// starting from the \c else keyword.
+RangeSelector elseBranch(std::string ID);
+
 /// Selects the range from which `S` was expanded (possibly along with other
 /// source), if `S` is an expansion, and `S` itself, otherwise.  Corresponds to
 /// `SourceManager::getExpansionRange`.
 RangeSelector expansion(RangeSelector S);
+
+/// Chooses between the two selectors, based on whether \p ID is bound in the
+/// match.
+RangeSelector ifBound(std::string ID, RangeSelector TrueSelector,
+  RangeSelector FalseSelector);
 } // namespace tooling
 } // namespace clang
 
Index: cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
===
--- cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
+++ cfe/trunk/lib/Tooling/Refactoring/RangeSelector.cpp
@@ -219,6 +219,9 @@
 }
 
 namespace {
+// FIXME: make this available in the public API for users to easily create their
+// own selectors.
+
 // Creates a selector from a range-selection function \p Func, which selects a
 // range that is relative to a bound node id.  \c T is the node type expected by
 // \p Func.
@@ -286,6 +289,19 @@
   return RelativeSelector(std::move(ID));
 }
 
+namespace {
+// Returns the range of the else branch, including the `else` keyword.
+CharSourceRange getElseRange(const MatchResult &Result, const IfStmt &S) {
+  return maybeExtendRange(
+  CharSourceRange::getTokenRange(S.getElseLoc(), S.getEndLoc()),
+  tok::TokenKind::semi, *Result.Context);
+}
+} // namespace
+
+RangeSelector tooling::elseBranch(std::string ID) {
+  return RelativeSelector(std::move(ID));
+}
+
 RangeSelector tooling::expansion(RangeSelector S) {
   return [S](const MatchResult &Result) -> Expected {
 Expected SRange = S(Result);
@@ -294,3 +310,11 @@
 return Result.SourceManager->getExpansionRange(*SRange);

[PATCH] D67719: [clang] [Basic] Enable __has_feature(leak_sanitizer)

2019-09-20 Thread Petr Hosek via Phabricator via cfe-commits
phosek accepted this revision.
phosek added a comment.
This revision is now accepted and ready to land.

LGTM


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

https://reviews.llvm.org/D67719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67719: [clang] [Basic] Enable __has_feature(leak_sanitizer)

2019-09-20 Thread Petr Hosek via Phabricator via cfe-commits
phosek requested changes to this revision.
phosek added a comment.
This revision now requires changes to proceed.

Actually, can you please add a test akin to 
https://github.com/llvm/llvm-project/blob/master/clang/test/Lexer/has_feature_memory_sanitizer.cpp?


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

https://reviews.llvm.org/D67719



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67843: DisableFormat also now disables SortIncludes

2019-09-20 Thread Sam Maier via Phabricator via cfe-commits
SamMaier created this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
SamMaier added a reviewer: thakis.

Previously, in order to have clang-format //not// format something, you had to 
give both:

  SortIncludes: false
  DisableFormat: true

This is confusing to users, who would expect that DisableFormat does what it 
says, and prevents clang-format from editing any files it applies to. See 
https://stackoverflow.com/questions/55833838/clang-format-still-formatting-with-disableformat-true
 for example.


Repository:
  rC Clang

https://reviews.llvm.org/D67843

Files:
  clang/lib/Format/Format.cpp
  clang/test/Format/disable-format.cpp


Index: clang/test/Format/disable-format.cpp
===
--- clang/test/Format/disable-format.cpp
+++ clang/test/Format/disable-format.cpp
@@ -1,5 +1,9 @@
 // RUN: grep -Ev "// *[A-Z-]+:" %s | clang-format -style=none \
 // RUN:   | FileCheck -strict-whitespace %s

-// CHECK: int   i;
+// CHECK: #include 
+// CHECK-NEXT: #include 
+// CHECK-NEXT: int   i;
+#include 
+#include 
 int   i;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -1062,8 +1062,6 @@
 FormatStyle getNoStyle() {
   FormatStyle NoStyle = getLLVMStyle();
   NoStyle.DisableFormat = true;
-  NoStyle.SortIncludes = false;
-  NoStyle.SortUsingDeclarations = false;
   return NoStyle;
 }

@@ -2130,7 +2128,7 @@
ArrayRef Ranges,
StringRef FileName, unsigned *Cursor) {
   tooling::Replacements Replaces;
-  if (!Style.SortIncludes)
+  if (!Style.SortIncludes || Style.DisableFormat)
 return Replaces;
   if (isLikelyXml(Code))
 return Replaces;


Index: clang/test/Format/disable-format.cpp
===
--- clang/test/Format/disable-format.cpp
+++ clang/test/Format/disable-format.cpp
@@ -1,5 +1,9 @@
 // RUN: grep -Ev "// *[A-Z-]+:" %s | clang-format -style=none \
 // RUN:   | FileCheck -strict-whitespace %s

-// CHECK: int   i;
+// CHECK: #include 
+// CHECK-NEXT: #include 
+// CHECK-NEXT: int   i;
+#include 
+#include 
 int   i;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -1062,8 +1062,6 @@
 FormatStyle getNoStyle() {
   FormatStyle NoStyle = getLLVMStyle();
   NoStyle.DisableFormat = true;
-  NoStyle.SortIncludes = false;
-  NoStyle.SortUsingDeclarations = false;
   return NoStyle;
 }

@@ -2130,7 +2128,7 @@
ArrayRef Ranges,
StringRef FileName, unsigned *Cursor) {
   tooling::Replacements Replaces;
-  if (!Style.SortIncludes)
+  if (!Style.SortIncludes || Style.DisableFormat)
 return Replaces;
   if (isLikelyXml(Code))
 return Replaces;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67843: DisableFormat also now disables SortIncludes

2019-09-20 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

Makes sense to me, but krasimir should probably approve this.

Please upload patches with lots of context (`git diff -U master`); that 
makes reviewing on phab easier.


Repository:
  rC Clang

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

https://reviews.llvm.org/D67843



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67843: DisableFormat also now disables SortIncludes

2019-09-20 Thread Sam Maier via Phabricator via cfe-commits
SamMaier updated this revision to Diff 221065.
SamMaier added a comment.

Diff with more context


Repository:
  rC Clang

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

https://reviews.llvm.org/D67843

Files:
  clang/lib/Format/Format.cpp
  clang/test/Format/disable-format.cpp


Index: clang/test/Format/disable-format.cpp
===
--- clang/test/Format/disable-format.cpp
+++ clang/test/Format/disable-format.cpp
@@ -1,5 +1,9 @@
 // RUN: grep -Ev "// *[A-Z-]+:" %s | clang-format -style=none \
 // RUN:   | FileCheck -strict-whitespace %s
 
-// CHECK: int   i;
+// CHECK: #include 
+// CHECK-NEXT: #include 
+// CHECK-NEXT: int   i;
+#include 
+#include 
 int   i;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -1062,8 +1062,6 @@
 FormatStyle getNoStyle() {
   FormatStyle NoStyle = getLLVMStyle();
   NoStyle.DisableFormat = true;
-  NoStyle.SortIncludes = false;
-  NoStyle.SortUsingDeclarations = false;
   return NoStyle;
 }
 
@@ -2130,7 +2128,7 @@
ArrayRef Ranges,
StringRef FileName, unsigned *Cursor) {
   tooling::Replacements Replaces;
-  if (!Style.SortIncludes)
+  if (!Style.SortIncludes || Style.DisableFormat)
 return Replaces;
   if (isLikelyXml(Code))
 return Replaces;


Index: clang/test/Format/disable-format.cpp
===
--- clang/test/Format/disable-format.cpp
+++ clang/test/Format/disable-format.cpp
@@ -1,5 +1,9 @@
 // RUN: grep -Ev "// *[A-Z-]+:" %s | clang-format -style=none \
 // RUN:   | FileCheck -strict-whitespace %s
 
-// CHECK: int   i;
+// CHECK: #include 
+// CHECK-NEXT: #include 
+// CHECK-NEXT: int   i;
+#include 
+#include 
 int   i;
Index: clang/lib/Format/Format.cpp
===
--- clang/lib/Format/Format.cpp
+++ clang/lib/Format/Format.cpp
@@ -1062,8 +1062,6 @@
 FormatStyle getNoStyle() {
   FormatStyle NoStyle = getLLVMStyle();
   NoStyle.DisableFormat = true;
-  NoStyle.SortIncludes = false;
-  NoStyle.SortUsingDeclarations = false;
   return NoStyle;
 }
 
@@ -2130,7 +2128,7 @@
ArrayRef Ranges,
StringRef FileName, unsigned *Cursor) {
   tooling::Replacements Replaces;
-  if (!Style.SortIncludes)
+  if (!Style.SortIncludes || Style.DisableFormat)
 return Replaces;
   if (isLikelyXml(Code))
 return Replaces;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372414 - Reland '[analyzer][MallocChecker][NFC] Document and reorganize some functions'

2019-09-20 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Sep 20 10:59:20 2019
New Revision: 372414

URL: http://llvm.org/viewvc/llvm-project?rev=372414&view=rev
Log:
Reland '[analyzer][MallocChecker][NFC] Document and reorganize some functions'

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

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=372414&r1=372413&r2=372414&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Fri Sep 20 10:59:20 
2019
@@ -6,8 +6,41 @@
 //
 
//===--===//
 //
-// This file defines malloc/free checker, which checks for potential memory
-// leaks, double free, and use-after-free problems.
+// This file defines a variety of memory management related checkers, such as
+// leak, double free, and use-after-free.
+//
+// The following checkers are defined here:
+//
+//   * MallocChecker
+//   Despite its name, it models all sorts of memory allocations and
+//   de- or reallocation, including but not limited to malloc, free,
+//   relloc, new, delete. It also reports on a variety of memory misuse
+//   errors.
+//   Many other checkers interact very closely with this checker, in fact,
+//   most are merely options to this one. Other checkers may register
+//   MallocChecker, but do not enable MallocChecker's reports (more details
+//   to follow around its field, ChecksEnabled).
+//   It also has a boolean "Optimistic" checker option, which if set to 
true
+//   will cause the checker to model user defined memory management related
+//   functions annotated via the attribute ownership_takes, ownership_holds
+//   and ownership_returns.
+//
+//   * NewDeleteChecker
+//   Enables the modeling of new, new[], delete, delete[] in MallocChecker,
+//   and checks for related double-free and use-after-free errors.
+//
+//   * NewDeleteLeaksChecker
+//   Checks for leaks related to new, new[], delete, delete[].
+//   Depends on NewDeleteChecker.
+//
+//   * MismatchedDeallocatorChecker
+//   Enables checking whether memory is deallocated with the correspending
+//   allocation function in MallocChecker, such as malloc() allocated
+//   regions are only freed by free(), new by delete, new[] by delete[].
+//
+//  InnerPointerChecker interacts very closely with MallocChecker, but unlike
+//  the above checkers, it has it's own file, hence the many 
InnerPointerChecker
+//  related headers and non-static functions.
 //
 
//===--===//
 
@@ -37,6 +70,10 @@
 using namespace clang;
 using namespace ento;
 
+//===--===//
+// The types of allocation we're modeling.
+//===--===//
+
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
@@ -50,57 +87,88 @@ enum AllocationFamily {
   AF_InnerBuffer
 };
 
+struct MemFunctionInfoTy;
+
+} // end of anonymous namespace
+
+/// Determine family of a deallocation expression.
+static AllocationFamily
+getAllocationFamily(const MemFunctionInfoTy &MemFunctionInfo, CheckerContext 
&C,
+const Stmt *S);
+
+/// Print names of allocators and deallocators.
+///
+/// \returns true on success.
+static bool printAllocDeallocName(raw_ostream &os, CheckerContext &C,
+  const Expr *E);
+
+/// Print expected name of an allocator based on the deallocator's
+/// family derived from the DeallocExpr.
+static void printExpectedAllocName(raw_ostream &os,
+   const MemFunctionInfoTy &MemFunctionInfo,
+   CheckerContext &C, const Expr *E);
+
+/// Print expected name of a deallocator based on the allocator's
+/// family.
+static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family);
+
+//===--===//
+// The state of a symbol, in terms of memory management.
+//===--===//
+
+namespace {
+
 class RefState {
-  enum Kind { // Reference to allocated memory.
-  Allocated,
-  // Reference to zero-allocated memory.
-  AllocatedOfSizeZero,
-  // Reference to released/freed memory.
-  Released,
-  // The responsibility for freeing resources has transferred from
-  // this reference. A relinquished symbol should not be freed.
-  Relinquished,
- 

[PATCH] D67774: [Mangle] Add flag to asm labels to disable global prefixing

2019-09-20 Thread Vedant Kumar via Phabricator via cfe-commits
vsk updated this revision to Diff 221066.
vsk retitled this revision from "[Mangle] Check ExternalASTSource before adding 
prefix to asm label names" to "[Mangle] Add flag to asm labels to disable 
global prefixing".
vsk edited the summary of this revision.
vsk added a comment.

Thanks for your feedback. I've added a flag to asm labels to disable global 
prefixing. I've tried to minimize the behavior change in this patch -- it seems 
to me that additional cleanups can happen in follow-ups.


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

https://reviews.llvm.org/D67774

Files:
  clang/include/clang/Basic/Attr.td
  clang/lib/AST/Mangle.cpp
  clang/lib/Sema/SemaDecl.cpp
  clang/unittests/AST/DeclTest.cpp
  lldb/source/Symbol/ClangASTContext.cpp

Index: lldb/source/Symbol/ClangASTContext.cpp
===
--- lldb/source/Symbol/ClangASTContext.cpp
+++ lldb/source/Symbol/ClangASTContext.cpp
@@ -8300,8 +8300,8 @@
 cxx_method_decl->addAttr(clang::UsedAttr::CreateImplicit(*getASTContext()));
 
   if (mangled_name != nullptr) {
-cxx_method_decl->addAttr(
-clang::AsmLabelAttr::CreateImplicit(*getASTContext(), mangled_name));
+cxx_method_decl->addAttr(clang::AsmLabelAttr::CreateImplicit(
+*getASTContext(), mangled_name, /*literal=*/true));
   }
 
   // Populate the method decl with parameter decls
Index: clang/unittests/AST/DeclTest.cpp
===
--- clang/unittests/AST/DeclTest.cpp
+++ clang/unittests/AST/DeclTest.cpp
@@ -10,12 +10,16 @@
 //
 //===--===//
 
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Mangle.h"
+#include "clang/Basic/LLVM.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Tooling/Tooling.h"
 #include "gtest/gtest.h"
 
 using namespace clang::ast_matchers;
 using namespace clang::tooling;
+using namespace clang;
 
 TEST(Decl, CleansUpAPValues) {
   MatchFinder Finder;
@@ -56,3 +60,49 @@
   "constexpr _Complex __uint128_t c = 0x;",
   Args));
 }
+
+TEST(Decl, AsmLabelAttr) {
+  // Create two method decls: `f` and `g`.
+  StringRef Code = R"(
+struct S {
+  void f() {}
+  void g() {}
+};
+  )";
+  auto AST =
+  tooling::buildASTFromCodeWithArgs(Code, {"-target", "i386-apple-darwin"});
+  ASTContext &Ctx = AST->getASTContext();
+  DiagnosticsEngine &Diags = AST->getDiagnostics();
+  SourceManager &SM = AST->getSourceManager();
+  FileID MainFileID = SM.getMainFileID();
+
+  // Find the method decls within the AST.
+  SmallVector Decls;
+  AST->findFileRegionDecls(MainFileID, Code.find('{'), 0, Decls);
+  ASSERT_TRUE(Decls.size() == 1);
+  CXXRecordDecl *DeclS = cast(Decls[0]);
+  NamedDecl *DeclF = *DeclS->method_begin();
+  NamedDecl *DeclG = *(++DeclS->method_begin());
+
+  // Attach asm labels to the decls: one literal, and one subject to global
+  // prefixing.
+  DeclF->addAttr(::new (Ctx) AsmLabelAttr(Ctx, SourceLocation(), "foo",
+  /*LiteralLabel=*/true));
+  DeclG->addAttr(::new (Ctx) AsmLabelAttr(Ctx, SourceLocation(), "goo",
+  /*LiteralLabel=*/false));
+
+  // Mangle the decl names.
+  std::string MangleF, MangleG;
+  MangleContext *MC = ItaniumMangleContext::create(Ctx, Diags);
+  {
+llvm::raw_string_ostream OS(MangleF);
+MC->mangleName(DeclF, OS);
+  }
+  {
+llvm::raw_string_ostream OS(MangleG);
+MC->mangleName(DeclG, OS);
+  }
+
+  ASSERT_TRUE(0 == MangleF.compare("foo"));
+  ASSERT_TRUE(0 == MangleG.compare("\x01goo"));
+}
Index: clang/lib/Sema/SemaDecl.cpp
===
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -2766,6 +2766,8 @@
 
   if (AsmLabelAttr *NewA = New->getAttr()) {
 if (AsmLabelAttr *OldA = Old->getAttr()) {
+  assert(OldA->getLiteralLabel() == NewA->getLiteralLabel() &&
+ "Redeclaration of asm label changes label kind");
   if (OldA->getLabel() != NewA->getLabel()) {
 // This redeclaration changes __asm__ label.
 Diag(New->getLocation(), diag::err_different_asm_label);
@@ -6983,8 +6985,8 @@
   }
 }
 
-NewVD->addAttr(::new (Context)
-   AsmLabelAttr(Context, SE->getStrTokenLoc(0), Label));
+NewVD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getStrTokenLoc(0),
+Label, /*LiteralLabel=*/false));
   } else if (!ExtnameUndeclaredIdentifiers.empty()) {
 llvm::DenseMap::iterator I =
   ExtnameUndeclaredIdentifiers.find(NewVD->getIdentifier());
@@ -8882,8 +8884,9 @@
   if (Expr *E = (Expr*) D.getAsmLabel()) {
 // The parser guarantees this is a string.
 StringLiteral *SE = cast(E);
-NewFD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getStrTokenLoc(0),
-

[PATCH] D54823: [analyzer][MallocChecker][NFC] Document and reorganize some functions

2019-09-20 Thread Kristóf Umann via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL372414: Reland '[analyzer][MallocChecker][NFC] Document 
and reorganize some functions' (authored by Szelethus, committed by ).
Herald added a project: LLVM.

Changed prior to commit:
  https://reviews.llvm.org/D54823?vs=220873&id=221073#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D54823

Files:
  cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Index: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -6,8 +6,41 @@
 //
 //===--===//
 //
-// This file defines malloc/free checker, which checks for potential memory
-// leaks, double free, and use-after-free problems.
+// This file defines a variety of memory management related checkers, such as
+// leak, double free, and use-after-free.
+//
+// The following checkers are defined here:
+//
+//   * MallocChecker
+//   Despite its name, it models all sorts of memory allocations and
+//   de- or reallocation, including but not limited to malloc, free,
+//   relloc, new, delete. It also reports on a variety of memory misuse
+//   errors.
+//   Many other checkers interact very closely with this checker, in fact,
+//   most are merely options to this one. Other checkers may register
+//   MallocChecker, but do not enable MallocChecker's reports (more details
+//   to follow around its field, ChecksEnabled).
+//   It also has a boolean "Optimistic" checker option, which if set to true
+//   will cause the checker to model user defined memory management related
+//   functions annotated via the attribute ownership_takes, ownership_holds
+//   and ownership_returns.
+//
+//   * NewDeleteChecker
+//   Enables the modeling of new, new[], delete, delete[] in MallocChecker,
+//   and checks for related double-free and use-after-free errors.
+//
+//   * NewDeleteLeaksChecker
+//   Checks for leaks related to new, new[], delete, delete[].
+//   Depends on NewDeleteChecker.
+//
+//   * MismatchedDeallocatorChecker
+//   Enables checking whether memory is deallocated with the correspending
+//   allocation function in MallocChecker, such as malloc() allocated
+//   regions are only freed by free(), new by delete, new[] by delete[].
+//
+//  InnerPointerChecker interacts very closely with MallocChecker, but unlike
+//  the above checkers, it has it's own file, hence the many InnerPointerChecker
+//  related headers and non-static functions.
 //
 //===--===//
 
@@ -37,6 +70,10 @@
 using namespace clang;
 using namespace ento;
 
+//===--===//
+// The types of allocation we're modeling.
+//===--===//
+
 namespace {
 
 // Used to check correspondence between allocators and deallocators.
@@ -50,57 +87,88 @@
   AF_InnerBuffer
 };
 
+struct MemFunctionInfoTy;
+
+} // end of anonymous namespace
+
+/// Determine family of a deallocation expression.
+static AllocationFamily
+getAllocationFamily(const MemFunctionInfoTy &MemFunctionInfo, CheckerContext &C,
+const Stmt *S);
+
+/// Print names of allocators and deallocators.
+///
+/// \returns true on success.
+static bool printAllocDeallocName(raw_ostream &os, CheckerContext &C,
+  const Expr *E);
+
+/// Print expected name of an allocator based on the deallocator's
+/// family derived from the DeallocExpr.
+static void printExpectedAllocName(raw_ostream &os,
+   const MemFunctionInfoTy &MemFunctionInfo,
+   CheckerContext &C, const Expr *E);
+
+/// Print expected name of a deallocator based on the allocator's
+/// family.
+static void printExpectedDeallocName(raw_ostream &os, AllocationFamily Family);
+
+//===--===//
+// The state of a symbol, in terms of memory management.
+//===--===//
+
+namespace {
+
 class RefState {
-  enum Kind { // Reference to allocated memory.
-  Allocated,
-  // Reference to zero-allocated memory.
-  AllocatedOfSizeZero,
-  // Reference to released/freed memory.
-  Released,
-  // The responsibility for freeing resources has transferred from
-  // this reference. A relinquished symbol should not be freed.
-  Relinquished,
-  // We are no longer guaran

r372415 - [www] Turn 'Clang 9' boxes green in C++ status pages now Clang 9 is

2019-09-20 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Fri Sep 20 11:09:05 2019
New Revision: 372415

URL: http://llvm.org/viewvc/llvm-project?rev=372415&view=rev
Log:
[www] Turn 'Clang 9' boxes green in C++ status pages now Clang 9 is
released.

Modified:
cfe/trunk/www/cxx_dr_status.html
cfe/trunk/www/cxx_status.html
cfe/trunk/www/make_cxx_dr_status

Modified: cfe/trunk/www/cxx_dr_status.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=372415&r1=372414&r2=372415&view=diff
==
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Fri Sep 20 11:09:05 2019
@@ -9955,19 +9955,19 @@ and POD class
 http://wg21.link/cwg1690";>1690
 C++14
 Associated namespace for local type
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg1691";>1691
 C++14
 Argument-dependent lookup and opaque enumerations
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg1692";>1692
 C++14
 Associated namespaces of doubly-nested classes
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg1693";>1693
@@ -10147,7 +10147,7 @@ and POD class
 http://wg21.link/cwg1722";>1722
 CD4
 Should lambda to function pointer conversion function be 
noexcept?
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg1723";>1723
@@ -10483,7 +10483,7 @@ and POD class
 http://wg21.link/cwg1778";>1778
 C++14
 exception-specification in explicitly-defaulted functions
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg1779";>1779
@@ -11047,7 +11047,7 @@ and POD class
 http://wg21.link/cwg1872";>1872
 CD4
 Instantiations of constexpr templates that cannot appear in 
constant expressions
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg1873";>1873
@@ -12655,7 +12655,7 @@ and POD class
 http://wg21.link/cwg2140";>2140
 CD4
 Lvalue-to-rvalue conversion of std::nullptr_t
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg2141";>2141
@@ -12835,7 +12835,7 @@ and POD class
 http://wg21.link/cwg2170";>2170
 DR
 Unclear definition of odr-use for arrays
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg2171";>2171
@@ -13567,7 +13567,7 @@ and POD class
 http://wg21.link/cwg2292";>2292
 DRWP
 simple-template-id is ambiguous between class-name and 
type-name
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg2293";>2293
@@ -13933,7 +13933,7 @@ and POD class
 http://wg21.link/cwg2353";>2353
 DR
 Potential results of a member access expression for a static data 
member
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg2354";>2354
@@ -14131,13 +14131,13 @@ and POD class
 http://wg21.link/cwg2386";>2386
 DR
 tuple_size requirements for structured binding
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg2387";>2387
 DR
 Linkage of const-qualified variable template
-Clang 9
+Clang 9
   
   
 http://wg21.link/cwg2388";>2388

Modified: cfe/trunk/www/cxx_status.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=372415&r1=372414&r2=372415&view=diff
==
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Fri Sep 20 11:09:05 2019
@@ -114,7 +114,7 @@ with http://libcxx.llvm.org/";>l
 

 http://wg21.link/p1009r2";>P1009R2 (DR)
-Clang 9
+Clang 9
   
 
   Static assertions
@@ -289,7 +289,7 @@ with http://libcxx.llvm.org/";>l
 

 http://wg21.link/p1286r2";>P1286R2 (DR)
-Clang 9
+Clang 9
   
 
   Deleted functions
@@ -664,7 +664,7 @@ version 3.7.
 

 http://wg21.link/p1771r1";>P1771R1 (DR)
-Clang 9
+Clang 9
   
 
   [[maybe_unused]] attribute
@@ -866,7 +866,7 @@ as the draft C++2a standard evolves.
 

 http://wg21.link/p1042r1";>P1042R1
-Clang 9
+Clang 9
   
 
   Designated initializers
@@ -876,7 +876,7 @@ as the draft C++2a standard evolves.
 
   template-parameter-list for generic lambdas
   http://wg21.link/p0428r2";>P0428R2
-  Clang 9
+  Clang 9
 
 
   Concepts
@@ -910,7 +910,7 @@ as the draft C++2a standard evolves.
 
   ADL and function templates that are not visible
   http://wg21.link/p0846r0";>P0846R0
-  Clang 9
+  Clang 9
 
 
   const mismatch with defaulted copy constructor
@@ -957,7 +957,7 @@ as the draft C++2a standard evolves.
 
   [[no_unique_address]] attribute
   http://wg21.link/p0840r2";>P0840R2
-  Clang 9
+  Clang 9
 
 
   [[likely]] and [[unlikely]] attributes
@@ -972,7 +972,7 @@ as the draft C++2a standard evolves.
 
   Pack expansion in lambda init-capture
   http://wg21.link/p0780r2";>P0780R2
-  Clang 9

[PATCH] D67079: [analyzer] CastValueChecker: Model inheritance

2019-09-20 Thread Csaba Dabis via Phabricator via cfe-commits
Charusso updated this revision to Diff 221070.
Charusso marked 9 inline comments as done.
Charusso added a comment.

- Try to do the math.
- Create a consistent dynamic type API.


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

https://reviews.llvm.org/D67079

Files:
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicCastInfo.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicType.h
  clang/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeInfo.h
  clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/DynamicTypeChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
  clang/lib/StaticAnalyzer/Checkers/IteratorChecker.cpp
  clang/lib/StaticAnalyzer/Core/CallEvent.cpp
  clang/lib/StaticAnalyzer/Core/DynamicType.cpp
  clang/test/Analysis/cast-value-hierarchy-failures-set.cpp
  clang/test/Analysis/cast-value-hierarchy-succeeds.cpp
  clang/test/Analysis/cast-value-hierarchy.cpp
  clang/test/Analysis/cast-value-notes.cpp
  clang/test/Analysis/cast-value-state-dump.cpp
  clang/test/Analysis/expr-inspection.c

Index: clang/test/Analysis/expr-inspection.c
===
--- clang/test/Analysis/expr-inspection.c
+++ clang/test/Analysis/expr-inspection.c
@@ -38,7 +38,7 @@
 // CHECK-NEXT: { "symbol": "reg_$0", "range": "{ [-2147483648, 13] }" }
 // CHECK-NEXT:   ],
 // CHECK-NEXT:   "dynamic_types": null,
-// CHECK-NEXT:   "dynamic_casts": null,
+// CHECK-NEXT:   "failed_casts": null,
 // CHECK-NEXT:   "constructing_objects": null,
 // CHECK-NEXT:   "checker_messages": null
 // CHECK-NEXT: }
Index: clang/test/Analysis/cast-value-state-dump.cpp
===
--- clang/test/Analysis/cast-value-state-dump.cpp
+++ clang/test/Analysis/cast-value-state-dump.cpp
@@ -11,19 +11,31 @@
 class Triangle : public Shape {};
 class Circle : public Shape {};
 class Square : public Shape {};
+class Octagram : public Shape {};
 } // namespace clang
 
 using namespace llvm;
 using namespace clang;
 
 void evalNonNullParamNonNullReturn(const Shape *S) {
+  if (isa(S)) {
+// expected-note@-1 {{Assuming 'S' is not a 'Triangle'}}
+// expected-note@-2 {{Taking false branch}}
+return;
+  }
+
+  if (isa(S)) {
+// expected-note@-1 {{Assuming 'S' is not an 'Octagram'}}
+// expected-note@-2 {{Taking false branch}}
+return;
+  }
+
   const auto *C = dyn_cast_or_null(S);
   // expected-note@-1 {{Assuming 'S' is a 'Circle'}}
   // expected-note@-2 {{'C' initialized here}}
 
-  // FIXME: We assumed that 'S' is a 'Circle' therefore it is not a 'Square'.
   if (dyn_cast_or_null(S)) {
-// expected-note@-1 {{Assuming 'S' is not a 'Square'}}
+// expected-note@-1 {{'S' is not a 'Square'}}
 // expected-note@-2 {{Taking false branch}}
 return;
   }
@@ -33,11 +45,11 @@
   // CHECK:  "dynamic_types": [
   // CHECK-NEXT:   { "region": "SymRegion{reg_$0}", "dyn_type": "const class clang::Circle", "sub_classable": true }
   // CHECK-NEXT: ],
-  // CHECK-NEXT: "dynamic_casts": [
-  // CHECK:{ "region": "SymRegion{reg_$0}", "casts": [
-  // CHECK-NEXT: { "from": "const struct clang::Shape *", "to": "const class clang::Circle *", "kind": "success" },
-  // CHECK-NEXT: { "from": "const struct clang::Shape *", "to": "const class clang::Square *", "kind": "fail" }
+  // CHECK-NEXT: "failed_casts": [
+  // CHECK-NEXT:   { "region": "SymRegion{reg_$0}", "casts": [
+  // CHECK-NEXT: "const class clang::Square *", "class clang::Triangle *", "class clang::Octagram *"
   // CHECK-NEXT:   ]}
+  // CHECK-NEXT: ],
 
   (void)(1 / !C);
   // expected-note@-1 {{'C' is non-null}}
Index: clang/test/Analysis/cast-value-notes.cpp
===
--- clang/test/Analysis/cast-value-notes.cpp
+++ clang/test/Analysis/cast-value-notes.cpp
@@ -37,12 +37,6 @@
 return;
   }
 
-  if (dyn_cast_or_null(C)) {
-// expected-note@-1 {{Assuming 'C' is not a 'Triangle'}}
-// expected-note@-2 {{Taking false branch}}
-return;
-  }
-
   if (isa(C)) {
 // expected-note@-1 {{'C' is not a 'Triangle'}}
 // expected-note@-2 {{Taking false branch}}
@@ -65,14 +59,8 @@
   // expected-note@-1 {{'S' is a 'Circle'}}
   // expected-note@-2 {{'C' initialized here}}
 
-  if (!isa(C)) {
-// expected-note@-1 {{Assuming 'C' is a 'Triangle'}}
-// expected-note@-2 {{Taking false branch}}
-return;
-  }
-
-  if (!isa(C)) {
-// expected-note@-1 {{'C' is a 'Triangle'}}
+  if (isa(C)) {
+// expected-note@-1 {{'C' is not a 'Triangle'}}
 // expected-note@-2 {{Taking false branch}}
 return;
   }
Index: clang/test/Analysis/cast-value-hierarchy.cpp
===
--- /dev/null
+++ clang/test/Analysis/cast-value-hierarchy.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker

[PATCH] D67079: [analyzer] CastValueChecker: Model inheritance

2019-09-20 Thread Csaba Dabis via Phabricator via cfe-commits
Charusso added inline comments.



Comment at: clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp:126
+
+  // If the casts have a common anchestor it could not be a succeeded downcast.
+  for (const auto &PreviousBase : PreviousRD->bases())

NoQ wrote:
> Charusso wrote:
> > NoQ wrote:
> > > Counterexample:
> > > 
> > > ```
> > > struct A {};
> > > struct B : A {};
> > > struct C : A, B {};
> > > ```
> > > 
> > > Downcast from `C` to `B` should succeed, even though they have a common 
> > > ancestor `A` (which has the same `CXXRecordDecl` but currently isn't the 
> > > same object within `C`, but can be, if `B` declares `A` as a virtual 
> > > base).
> > So, even it is some kind of anti-pattern as a warning arrive immediately, 
> > now I allow `B` to `C` downcasts. Could you explain me more about that 
> > virtual idea, please? Based on this possible use-case in my mind two 
> > classes are on the same level as every of their bases/vbases are equals.
> > Could you explain me more about that virtual idea, please?
> 
> In the following variation:
> ```
> struct A {};
> struct B : virtual A {};
> struct C : A, B {};
> ```
> we have `C` contain only one instance of `A`: the layout of `B` within `C` 
> would merely refer to the instance of `A` within `C` instead of making its 
> own copy. In particular, the constructor of `B` within the constructor of `C` 
> would not initialize `C`'s instance of `A` because the constructor of `C` 
> will invoke the constructor of `A` directly (cf. D61816).
That is a cool example, thanks you!



Comment at: clang/lib/StaticAnalyzer/Checkers/CastValueChecker.cpp:174
+
+constexpr llvm::StringLiteral Vowels = "aeiou";
+

NoQ wrote:
> Charusso wrote:
> > NoQ wrote:
> > > Omg lol nice. Did you try to figure out how do other people normally do 
> > > it?
> > There is no function for that in `ADT/StringExtras.h` + `grep` did not 
> > help, so I realized it is a common way to match vowels. Do you know a 
> > better solution?
> I just realized that this is actually incorrect and the correct solution is 
> pretty hard to implement because the actual "//a// vs. //an//" rule deals 
> with sounds, not letters. Eg.: 
> 
> > Clang is an "LLVM native" C/C++/Objective-C compiler
> 
> has an "an" because it's read as "an //**e**//l-el-vee-am".
That is a cool idea, I will adjust `StringExtras.h` after that patch, for now 
please let us use that simple heuristic.


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

https://reviews.llvm.org/D67079



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53768: Add VerboseOutputStream to CompilerInstance

2019-09-20 Thread Scott Linder via Phabricator via cfe-commits
scott.linder updated this revision to Diff 221075.
scott.linder added a comment.

After reading again I think I understand the ask now. Is this closer to what 
you had in mind?


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

https://reviews.llvm.org/D53768

Files:
  include/clang/Frontend/CompilerInstance.h
  lib/Frontend/CompilerInstance.cpp
  unittests/Frontend/OutputStreamTest.cpp

Index: unittests/Frontend/OutputStreamTest.cpp
===
--- unittests/Frontend/OutputStreamTest.cpp
+++ unittests/Frontend/OutputStreamTest.cpp
@@ -10,6 +10,7 @@
 #include "clang/CodeGen/BackendUtil.h"
 #include "clang/CodeGen/CodeGenAction.h"
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/FrontendTool/Utils.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "gtest/gtest.h"
@@ -43,4 +44,54 @@
   EXPECT_TRUE(!IRBuffer.empty());
   EXPECT_TRUE(StringRef(IRBuffer.data()).startswith("BC"));
 }
+
+TEST(FrontendOutputTests, TestVerboseOutputStreamShared) {
+  auto Invocation = std::make_shared();
+  Invocation->getPreprocessorOpts().addRemappedFile(
+  "test.cc", MemoryBuffer::getMemBuffer("invalid").release());
+  Invocation->getFrontendOpts().Inputs.push_back(
+  FrontendInputFile("test.cc", Language::CXX));
+  Invocation->getFrontendOpts().ProgramAction = EmitBC;
+  Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
+  CompilerInstance Compiler;
+
+  std::string VerboseBuffer;
+  raw_string_ostream VerboseStream(VerboseBuffer);
+
+  Compiler.setInvocation(std::move(Invocation));
+  IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
+  Compiler.createDiagnostics(
+  new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
+  Compiler.setVerboseOutputStream(VerboseStream);
+
+  bool Success = ExecuteCompilerInvocation(&Compiler);
+  EXPECT_FALSE(Success);
+  EXPECT_TRUE(!VerboseStream.str().empty());
+  EXPECT_TRUE(StringRef(VerboseBuffer.data()).contains("errors generated"));
+}
+
+TEST(FrontendOutputTests, TestVerboseOutputStreamOwned) {
+  auto Invocation = std::make_shared();
+  Invocation->getPreprocessorOpts().addRemappedFile(
+  "test.cc", MemoryBuffer::getMemBuffer("invalid").release());
+  Invocation->getFrontendOpts().Inputs.push_back(
+  FrontendInputFile("test.cc", Language::CXX));
+  Invocation->getFrontendOpts().ProgramAction = EmitBC;
+  Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
+  CompilerInstance Compiler;
+
+  std::string VerboseBuffer;
+  auto VerboseStream = std::make_unique(VerboseBuffer);
+
+  Compiler.setInvocation(std::move(Invocation));
+  IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
+  Compiler.createDiagnostics(
+  new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
+  Compiler.setVerboseOutputStream(VerboseStream);
+
+  bool Success = ExecuteCompilerInvocation(&Compiler);
+  EXPECT_FALSE(Success);
+  EXPECT_TRUE(!VerboseStream.str().empty());
+  EXPECT_TRUE(StringRef(VerboseBuffer.data()).contains("errors generated"));
+}
 }
Index: lib/Frontend/CompilerInstance.cpp
===
--- lib/Frontend/CompilerInstance.cpp
+++ lib/Frontend/CompilerInstance.cpp
@@ -86,6 +86,16 @@
   Diagnostics = Value;
 }
 
+void CompilerInstance::setVerboseOutputStream(raw_ostream &Value) {
+  OwnedVerboseOutputStream.release();
+  VerboseOutputStream = &Value;
+}
+
+void CompilerInstance::setVerboseOutputStream(std::unique_ptr Value) {
+  OwnedVerboseOutputStream.swap(Value);
+  VerboseOutputStream = OwnedVerboseOutputStream.get();
+}
+
 void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; }
 void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }
 
@@ -897,9 +907,7 @@
   // DesiredStackSpace available.
   noteBottomOfStack();
 
-  // FIXME: Take this as an argument, once all the APIs we used have moved to
-  // taking it as an input instead of hard-coding llvm::errs.
-  raw_ostream &OS = llvm::errs();
+  raw_ostream &OS = getVerboseOutputStream();
 
   if (!Act.PrepareToExecute(*this))
 return false;
Index: include/clang/Frontend/CompilerInstance.h
===
--- include/clang/Frontend/CompilerInstance.h
+++ include/clang/Frontend/CompilerInstance.h
@@ -155,6 +155,12 @@
   /// One or more modules failed to build.
   bool ModuleBuildFailed = false;
 
+  /// The stream for verbose output if owned, otherwise nullptr.
+  std::unique_ptr OwnedVerboseOutputStream;
+
+  /// The stream for verbose output.
+  raw_ostream *VerboseOutputStream = &llvm::errs();
+
   /// Holds information about the output file.
   ///
   /// If TempFilename is not empty we must rename it to Filename at the end.
@@ -217,9 +223,6 @@
   /// \param Act - The action to execute.
   /// \return - True on success.
   //
-  // FIXME: This function should take the stream to write 

[PATCH] D67079: [analyzer] CastValueChecker: Model inheritance

2019-09-20 Thread Kristóf Umann via Phabricator via cfe-commits
Szelethus added inline comments.



Comment at: clang/lib/StaticAnalyzer/Core/DynamicType.cpp:44
+
+bool isDerivedFrom(QualType X, QualType Y) {
+  const CXXRecordDecl *XRD = X->getPointeeCXXRecordDecl();

Hmm, I think this function answers the question, at least in the standard 
library sense, whether Y `std::is_base_of` of X, whereas "is derived from?" is 
another term that is used by clang and seems to not allow equality of types. 
Should we rename this to `isBaseOf`?


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

https://reviews.llvm.org/D67079



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372419 - Fix a documentation error

2019-09-20 Thread Kristof Umann via cfe-commits
Author: szelethus
Date: Fri Sep 20 11:28:04 2019
New Revision: 372419

URL: http://llvm.org/viewvc/llvm-project?rev=372419&view=rev
Log:
Fix a documentation error

Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=372419&r1=372418&r2=372419&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Fri Sep 20 11:28:04 
2019
@@ -550,7 +550,7 @@ private:
   /// Models memory reallocation.
   ///
   /// \param [in] CE The expression that reallocated memory
-  /// \param [in] FreesMemOnFailure Whether if reallocation fails, the supplied
+  /// \param [in] ShouldFreeOnFail Whether if reallocation fails, the supplied
   ///   memory should be freed.
   /// \param [in] State The \c ProgramState right before reallocation.
   /// \param [in] SuffixWithN Whether the reallocation function we're modeling


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67854: Ensure AtomicExpr goes through SEMA checking after TreeTransform

2019-09-20 Thread Erich Keane via Phabricator via cfe-commits
erichkeane created this revision.
erichkeane added a reviewer: eli.friedman.
Herald added a subscriber: jfb.

RebuildAtomicExpr was skipping doing semantic analysis which broke in
the cases where the expressions were not dependent. This resulted in the
ImplicitCastExpr from an array to a pointer being lost, causing a crash
in IR CodeGen.


https://reviews.llvm.org/D67854

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaChecking.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/AST/atomic-expr.cpp

Index: clang/test/AST/atomic-expr.cpp
===
--- /dev/null
+++ clang/test/AST/atomic-expr.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -ast-dump %s | FileCheck %s
+
+template
+void pr43370() {
+  int arr[2];
+  __atomic_store_n(arr, 0, 0);
+}
+void useage(){
+  pr43370();
+}
+
+// CHECK:FunctionTemplateDecl 0x{{[0-9a-f]+}} <{{[^:]+}}:3:1, line:7:1> line:4:6 pr43370
+// CHECK: AtomicExpr
+// CHECK-NEXT: ImplicitCastExpr
+// CHECK-SAME: 
+// CHECK:FunctionDecl 0x{{[0-9a-f]+}}  line:4:6 used pr43370
+// CHECK: AtomicExpr
+// CHECK-NEXT: ImplicitCastExpr
+// CHECK-SAME: 
Index: clang/lib/Sema/TreeTransform.h
===
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -3310,14 +3310,12 @@
   /// Subclasses may override this routine to provide different behavior.
   ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc,
MultiExprArg SubExprs,
-   QualType RetTy,
AtomicExpr::AtomicOp Op,
SourceLocation RParenLoc) {
-// Just create the expression; there is not any interesting semantic
-// analysis here because we can't actually build an AtomicExpr until
-// we are sure it is semantically sound.
-return new (SemaRef.Context) AtomicExpr(BuiltinLoc, SubExprs, RetTy, Op,
-RParenLoc);
+// Use this for all of the locations, since we don't know the difference
+// between the call and the expr at this point.
+SourceRange Range{BuiltinLoc, RParenLoc};
+return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op);
   }
 
 private:
@@ -12673,7 +12671,6 @@
 template
 ExprResult
 TreeTransform::TransformAtomicExpr(AtomicExpr *E) {
-  QualType RetTy = getDerived().TransformType(E->getType());
   bool ArgumentChanged = false;
   SmallVector SubExprs;
   SubExprs.reserve(E->getNumSubExprs());
@@ -12686,7 +12683,7 @@
 return E;
 
   return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
-RetTy, E->getOp(), E->getRParenLoc());
+E->getOp(), E->getRParenLoc());
 }
 
 //===--===//
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -4475,7 +4475,15 @@
  AtomicExpr::AtomicOp Op) {
   CallExpr *TheCall = cast(TheCallResult.get());
   DeclRefExpr *DRE =cast(TheCall->getCallee()->IgnoreParenCasts());
+  MultiExprArg Args{TheCall->getArgs(), TheCall->getNumArgs()};
+  return BuildAtomicExpr({TheCall->getBeginLoc(), TheCall->getEndLoc()},
+ DRE->getSourceRange(), TheCall->getRParenLoc(), Args,
+ Op);
+}
 
+ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
+ SourceLocation RParenLoc, MultiExprArg Args,
+ AtomicExpr::AtomicOp Op) {
   // All the non-OpenCL operations take one of the following forms.
   // The OpenCL operations take the __c11 forms with one extra argument for
   // synchronization scope.
@@ -4622,21 +4630,21 @@
   if (IsOpenCL && Op != AtomicExpr::AO__opencl_atomic_init)
 ++AdjustedNumArgs;
   // Check we have the right number of arguments.
-  if (TheCall->getNumArgs() < AdjustedNumArgs) {
-Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args)
-<< 0 << AdjustedNumArgs << TheCall->getNumArgs()
-<< TheCall->getCallee()->getSourceRange();
+  if (Args.size() < AdjustedNumArgs) {
+Diag(CallRange.getEnd(), diag::err_typecheck_call_too_few_args)
+<< 0 << AdjustedNumArgs << static_cast(Args.size())
+<< ExprRange;
 return ExprError();
-  } else if (TheCall->getNumArgs() > AdjustedNumArgs) {
-Diag(TheCall->getArg(AdjustedNumArgs)->getBeginLoc(),
+  } else if (Args.size() > AdjustedNumArgs) {
+Diag(Args[AdjustedNumArgs]->getBeginLoc(),
  diag::err_typecheck_call_too_many_args)
-<< 0 << AdjustedNumArgs << TheCall->getNumArgs()
-<< TheCall->getCallee()->getSourceRange();
+<< 0 << AdjustedNumArgs << static_cast(Args.size())
+

[PATCH] D67632: [libTooling] Introduce new library of source-code builders.

2019-09-20 Thread Dmitri Gribenko via Phabricator via cfe-commits
gribozavr added inline comments.



Comment at: clang/lib/Tooling/Refactoring/SourceCodeBuilders.cpp:68
+std::string tooling::buildParens(const Expr &E, const ASTContext &Context) {
+  StringRef ExprText = getText(E, Context);
+  if (mayNeedParens(E))

ymandel wrote:
> gribozavr wrote:
> > `buildDereference` below checks for `getText` returning an empty string; 
> > this function does not. Why?
> Regarding this and the issue of returning `llvm::Optional`: the code overall 
> is rather inconsistent in its handling of empty strings returned from 
> `getText`. This is only one example.
> 
> sorry for this -- this code was mostly collected from various other places in 
> the codebase and I should have looked it over more carefully.
> 
> With that said -- I think we need to decide whether we systematically assume 
> that `getText` doesn't return an empty string, or systematically check for it 
> and return llvm::None in that case.  We have the choice becuase there is no 
> risk of UB from ignoring the empty text.   Any checks in the code seem only 
> designed to propagate the "emptiness" for the caller's sake.
> 
> I'm inclined to state a precondition on the all of the functions that 
> `getText(E)` is non empty, rather than sprinkle optionals throughout the API. 
> My reasoning is that checking the result of these functions is "too late" in 
> the process. A failure here is caused by passing a node that has no 
> corresponding source code. If the caller is potentially dealing with such 
> phantom nodes, they should know that before trying to construct code with 
> them. Any check they can do on the result of `getText` they should have done 
> earlier with a more appropriate predicate of the node.
> 
> That said, I understand the preference for defensiveness (don't assume the 
> caller will get it right). I'm also fine with a compromise of asserting the 
> non-emptiness of any internal call to `getText` although that might be almost 
> as messy as just handling it.
> 
> WDYT?
It is true that there is no risk of UB (in terms of C++ spec), but there is a 
garbage-in/garbage-out issue. I don't think users will appreciate garbage out, 
because I don't think they have the ability to check the precondition properly 
-- after all, they don't know how exactly `getText` will be called.

Even if we figure out how to specify for users to check the precondition, they 
would always have to check it in order to use these APIs properly. After all, 
the source transformation tools that users write can't generally assume what 
code *their users* will throw at those tools. And if someone wants to throw 
together a simple tool prototype, they can always force-unwrap the optional, it 
is just an extra `*`.

Therefore, I believe embedding the check in these APIs will create a 
significantly better usage experience, and does not create much of a burden for 
users who don't want to handle errors.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67632



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67414: [AST] Treat "inline gnu_inline" the same way as "extern inline gnu_inline" in C++ mode

2019-09-20 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo updated this revision to Diff 221086.
mstorsjo added a comment.

Updated the CUDA test based on the suggestion.

@rsmith - What do you think of this version, the warning message, and the 
invariants for the `isInlineDefinitionExternallyVisible` method?


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

https://reviews.llvm.org/D67414

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/AST/Decl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/CodeGen/inline.c
  clang/test/SemaCUDA/gnu-inline.cu
  clang/test/SemaCXX/gnu_inline.cpp
  clang/test/SemaCXX/undefined-inline.cpp

Index: clang/test/SemaCXX/undefined-inline.cpp
===
--- clang/test/SemaCXX/undefined-inline.cpp
+++ clang/test/SemaCXX/undefined-inline.cpp
@@ -40,20 +40,20 @@
 }
 
 namespace test8 {
-  inline void foo() __attribute__((gnu_inline));
+  inline void foo() __attribute__((gnu_inline)); // expected-warning {{'gnu_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10}}
   void test() { foo(); }
 }
 
 namespace test9 {
   void foo();
   void test() { foo(); }
-  inline void foo() __attribute__((gnu_inline));
+  inline void foo() __attribute__((gnu_inline)); // expected-warning {{'gnu_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10}}
 }
 
 namespace test10 {
   inline void foo();
   void test() { foo(); }
-  inline void foo() __attribute__((gnu_inline));
+  inline void foo() __attribute__((gnu_inline)); // expected-warning {{'gnu_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10}}
 }
 
 namespace test11 {
Index: clang/test/SemaCXX/gnu_inline.cpp
===
--- /dev/null
+++ clang/test/SemaCXX/gnu_inline.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern inline
+__attribute__((__gnu_inline__))
+void gnu_inline1() {}
+
+inline
+__attribute__((__gnu_inline__)) // expected-warning {{'gnu_inline' attribute without 'extern' in C++ treated as externally available, this changed in Clang 10}}
+void gnu_inline2() {}
Index: clang/test/SemaCUDA/gnu-inline.cu
===
--- clang/test/SemaCUDA/gnu-inline.cu
+++ clang/test/SemaCUDA/gnu-inline.cu
@@ -7,4 +7,4 @@
 // Check that we can handle gnu_inline functions when compiling in CUDA mode.
 
 void foo();
-inline __attribute__((gnu_inline)) void bar() { foo(); }
+extern inline __attribute__((gnu_inline)) void bar() { foo(); }
Index: clang/test/CodeGen/inline.c
===
--- clang/test/CodeGen/inline.c
+++ clang/test/CodeGen/inline.c
@@ -52,7 +52,7 @@
 // CHECK3-LABEL: define i32 @_Z3barv()
 // CHECK3-LABEL: define linkonce_odr i32 @_Z3foov()
 // CHECK3-NOT: unreferenced
-// CHECK3-LABEL: define void @_Z10gnu_inlinev()
+// CHECK3-LABEL: define available_externally void @_Z10gnu_inlinev()
 // CHECK3-LABEL: define available_externally void @_Z13gnu_ei_inlinev()
 // CHECK3-NOT: @_Z5testCv
 // CHECK3-LABEL: define linkonce_odr i32 @_Z2eiv()
@@ -85,6 +85,7 @@
 extern __inline void unreferenced2() {}
 
 __inline __attribute((__gnu_inline__)) void gnu_inline() {}
+void (*P1)() = gnu_inline;
 
 // PR3988
 extern __inline __attribute__((gnu_inline)) void gnu_ei_inline() {}
Index: clang/lib/Sema/SemaDeclAttr.cpp
===
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -4253,6 +4253,9 @@
 return;
   }
 
+  if (S.LangOpts.CPlusPlus && Fn->getStorageClass() != SC_Extern)
+S.Diag(AL.getLoc(), diag::warn_gnu_inline_cplusplus_without_extern);
+
   D->addAttr(::new (S.Context) GNUInlineAttr(S.Context, AL));
 }
 
Index: clang/lib/AST/Decl.cpp
===
--- clang/lib/AST/Decl.cpp
+++ clang/lib/AST/Decl.cpp
@@ -3251,6 +3251,9 @@
   return true;
   }
 
+  if (Context.getLangOpts().CPlusPlus)
+return false;
+
   if (Context.getLangOpts().GNUInline || hasAttr()) {
 // With GNU inlining, a declaration with 'inline' but not 'extern', forces
 // an externally visible definition.
@@ -3279,9 +3282,6 @@
 return FoundBody;
   }
 
-  if (Context.getLangOpts().CPlusPlus)
-return false;
-
   // C99 6.7.4p6:
   //   [...] If all of the file scope declarations for a function in a
   //   translation unit include the inline function specifier without extern,
@@ -3361,6 +3361,8 @@
 // If it's not the case that both 'inline' and 'extern' are
 // specified on the definition, then this inline definition is
 // externally visible.
+if (Context.getLangOpts().CPlusPlus)
+  return false;
 if (!(isInlineSpecified() && getStorageClass() == SC_Extern))
   return true;
 
Index: clang/include/clang/Basic/DiagnosticS

r372422 - Ensure AtomicExpr goes through SEMA checking after TreeTransform

2019-09-20 Thread Erich Keane via cfe-commits
Author: erichkeane
Date: Fri Sep 20 12:17:31 2019
New Revision: 372422

URL: http://llvm.org/viewvc/llvm-project?rev=372422&view=rev
Log:
Ensure AtomicExpr goes through SEMA checking after TreeTransform

RebuildAtomicExpr was skipping doing semantic analysis which broke in
the cases where the expressions were not dependent. This resulted in the
ImplicitCastExpr from an array to a pointer being lost, causing a crash
in IR CodeGen.

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

Added:
cfe/trunk/test/AST/atomic-expr.cpp   (with props)
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/TreeTransform.h

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=372422&r1=372421&r2=372422&view=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Sep 20 12:17:31 2019
@@ -4637,6 +4637,9 @@ public:
MultiExprArg ArgExprs, SourceLocation RParenLoc,
Expr *ExecConfig = nullptr,
bool IsExecConfig = false);
+  ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
+ SourceLocation RParenLoc, MultiExprArg Args,
+ AtomicExpr::AtomicOp Op);
   ExprResult
   BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc,
 ArrayRef Arg, SourceLocation RParenLoc,

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=372422&r1=372421&r2=372422&view=diff
==
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Sep 20 12:17:31 2019
@@ -4475,7 +4475,15 @@ ExprResult Sema::SemaAtomicOpsOverloaded
  AtomicExpr::AtomicOp Op) {
   CallExpr *TheCall = cast(TheCallResult.get());
   DeclRefExpr *DRE 
=cast(TheCall->getCallee()->IgnoreParenCasts());
-
+  MultiExprArg Args{TheCall->getArgs(), TheCall->getNumArgs()};
+  return BuildAtomicExpr({TheCall->getBeginLoc(), TheCall->getEndLoc()},
+ DRE->getSourceRange(), TheCall->getRParenLoc(), Args,
+ Op);
+}
+
+ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
+ SourceLocation RParenLoc, MultiExprArg Args,
+ AtomicExpr::AtomicOp Op) {
   // All the non-OpenCL operations take one of the following forms.
   // The OpenCL operations take the __c11 forms with one extra argument for
   // synchronization scope.
@@ -4622,21 +4630,21 @@ ExprResult Sema::SemaAtomicOpsOverloaded
   if (IsOpenCL && Op != AtomicExpr::AO__opencl_atomic_init)
 ++AdjustedNumArgs;
   // Check we have the right number of arguments.
-  if (TheCall->getNumArgs() < AdjustedNumArgs) {
-Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args)
-<< 0 << AdjustedNumArgs << TheCall->getNumArgs()
-<< TheCall->getCallee()->getSourceRange();
+  if (Args.size() < AdjustedNumArgs) {
+Diag(CallRange.getEnd(), diag::err_typecheck_call_too_few_args)
+<< 0 << AdjustedNumArgs << static_cast(Args.size())
+<< ExprRange;
 return ExprError();
-  } else if (TheCall->getNumArgs() > AdjustedNumArgs) {
-Diag(TheCall->getArg(AdjustedNumArgs)->getBeginLoc(),
+  } else if (Args.size() > AdjustedNumArgs) {
+Diag(Args[AdjustedNumArgs]->getBeginLoc(),
  diag::err_typecheck_call_too_many_args)
-<< 0 << AdjustedNumArgs << TheCall->getNumArgs()
-<< TheCall->getCallee()->getSourceRange();
+<< 0 << AdjustedNumArgs << static_cast(Args.size())
+<< ExprRange;
 return ExprError();
   }
 
   // Inspect the first argument of the atomic operation.
-  Expr *Ptr = TheCall->getArg(0);
+  Expr *Ptr = Args[0];
   ExprResult ConvertedPtr = DefaultFunctionArrayLvalueConversion(Ptr);
   if (ConvertedPtr.isInvalid())
 return ExprError();
@@ -4644,7 +4652,7 @@ ExprResult Sema::SemaAtomicOpsOverloaded
   Ptr = ConvertedPtr.get();
   const PointerType *pointerType = Ptr->getType()->getAs();
   if (!pointerType) {
-Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer)
+Diag(ExprRange.getBegin(), diag::err_atomic_builtin_must_be_pointer)
 << Ptr->getType() << Ptr->getSourceRange();
 return ExprError();
   }
@@ -4654,13 +4662,13 @@ ExprResult Sema::SemaAtomicOpsOverloaded
   QualType ValType = AtomTy; // 'C'
   if (IsC11) {
 if (!AtomTy->isAtomicType()) {
-  Diag(DRE->getBeginLoc(), diag::err_atomic_op_needs_atomic)
+  Diag(ExprRange.getBegin(), diag::err_atomic_op_needs_atomic)
   << Ptr->getType() <

[PATCH] D67854: Ensure AtomicExpr goes through SEMA checking after TreeTransform

2019-09-20 Thread Erich Keane via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL372422: Ensure AtomicExpr goes through SEMA checking after 
TreeTransform (authored by erichkeane, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D67854?vs=221080&id=221088#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D67854

Files:
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/Sema/SemaChecking.cpp
  cfe/trunk/lib/Sema/TreeTransform.h
  cfe/trunk/test/AST/atomic-expr.cpp

Index: cfe/trunk/include/clang/Sema/Sema.h
===
--- cfe/trunk/include/clang/Sema/Sema.h
+++ cfe/trunk/include/clang/Sema/Sema.h
@@ -4637,6 +4637,9 @@
MultiExprArg ArgExprs, SourceLocation RParenLoc,
Expr *ExecConfig = nullptr,
bool IsExecConfig = false);
+  ExprResult BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
+ SourceLocation RParenLoc, MultiExprArg Args,
+ AtomicExpr::AtomicOp Op);
   ExprResult
   BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, SourceLocation LParenLoc,
 ArrayRef Arg, SourceLocation RParenLoc,
Index: cfe/trunk/test/AST/atomic-expr.cpp
===
--- cfe/trunk/test/AST/atomic-expr.cpp
+++ cfe/trunk/test/AST/atomic-expr.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -ast-dump %s | FileCheck %s
+
+template
+void pr43370() {
+  int arr[2];
+  __atomic_store_n(arr, 0, 0);
+}
+void useage(){
+  pr43370();
+}
+
+// CHECK:FunctionTemplateDecl 0x{{[0-9a-f]+}} <{{[^:]+}}:3:1, line:7:1> line:4:6 pr43370
+// CHECK: AtomicExpr
+// CHECK-NEXT: ImplicitCastExpr
+// CHECK-SAME: 
+// CHECK:FunctionDecl 0x{{[0-9a-f]+}}  line:4:6 used pr43370
+// CHECK: AtomicExpr
+// CHECK-NEXT: ImplicitCastExpr
+// CHECK-SAME: 
Index: cfe/trunk/lib/Sema/SemaChecking.cpp
===
--- cfe/trunk/lib/Sema/SemaChecking.cpp
+++ cfe/trunk/lib/Sema/SemaChecking.cpp
@@ -4475,7 +4475,15 @@
  AtomicExpr::AtomicOp Op) {
   CallExpr *TheCall = cast(TheCallResult.get());
   DeclRefExpr *DRE =cast(TheCall->getCallee()->IgnoreParenCasts());
+  MultiExprArg Args{TheCall->getArgs(), TheCall->getNumArgs()};
+  return BuildAtomicExpr({TheCall->getBeginLoc(), TheCall->getEndLoc()},
+ DRE->getSourceRange(), TheCall->getRParenLoc(), Args,
+ Op);
+}
 
+ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange,
+ SourceLocation RParenLoc, MultiExprArg Args,
+ AtomicExpr::AtomicOp Op) {
   // All the non-OpenCL operations take one of the following forms.
   // The OpenCL operations take the __c11 forms with one extra argument for
   // synchronization scope.
@@ -4622,21 +4630,21 @@
   if (IsOpenCL && Op != AtomicExpr::AO__opencl_atomic_init)
 ++AdjustedNumArgs;
   // Check we have the right number of arguments.
-  if (TheCall->getNumArgs() < AdjustedNumArgs) {
-Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args)
-<< 0 << AdjustedNumArgs << TheCall->getNumArgs()
-<< TheCall->getCallee()->getSourceRange();
+  if (Args.size() < AdjustedNumArgs) {
+Diag(CallRange.getEnd(), diag::err_typecheck_call_too_few_args)
+<< 0 << AdjustedNumArgs << static_cast(Args.size())
+<< ExprRange;
 return ExprError();
-  } else if (TheCall->getNumArgs() > AdjustedNumArgs) {
-Diag(TheCall->getArg(AdjustedNumArgs)->getBeginLoc(),
+  } else if (Args.size() > AdjustedNumArgs) {
+Diag(Args[AdjustedNumArgs]->getBeginLoc(),
  diag::err_typecheck_call_too_many_args)
-<< 0 << AdjustedNumArgs << TheCall->getNumArgs()
-<< TheCall->getCallee()->getSourceRange();
+<< 0 << AdjustedNumArgs << static_cast(Args.size())
+<< ExprRange;
 return ExprError();
   }
 
   // Inspect the first argument of the atomic operation.
-  Expr *Ptr = TheCall->getArg(0);
+  Expr *Ptr = Args[0];
   ExprResult ConvertedPtr = DefaultFunctionArrayLvalueConversion(Ptr);
   if (ConvertedPtr.isInvalid())
 return ExprError();
@@ -4644,7 +4652,7 @@
   Ptr = ConvertedPtr.get();
   const PointerType *pointerType = Ptr->getType()->getAs();
   if (!pointerType) {
-Diag(DRE->getBeginLoc(), diag::err_atomic_builtin_must_be_pointer)
+Diag(ExprRange.getBegin(), diag::err_atomic_builtin_must_be_pointer)
 << Ptr->getType() << Ptr->getSourceRange();
 return ExprError();
   }
@@ -4654,13 +4662,13 @@
   QualType ValType = AtomTy; // 'C'
   if (IsC11) {
 if (!AtomTy->isAtomicType()) {
-  Diag(DRE->getBeginLoc(), diag::err_atomic_op_

[PATCH] D53768: Add VerboseOutputStream to CompilerInstance

2019-09-20 Thread Scott Linder via Phabricator via cfe-commits
scott.linder updated this revision to Diff 221089.
scott.linder added a comment.

Same patch, this time with a working test.


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

https://reviews.llvm.org/D53768

Files:
  include/clang/Frontend/CompilerInstance.h
  lib/Frontend/CompilerInstance.cpp
  unittests/Frontend/OutputStreamTest.cpp

Index: unittests/Frontend/OutputStreamTest.cpp
===
--- unittests/Frontend/OutputStreamTest.cpp
+++ unittests/Frontend/OutputStreamTest.cpp
@@ -10,6 +10,7 @@
 #include "clang/CodeGen/BackendUtil.h"
 #include "clang/CodeGen/CodeGenAction.h"
 #include "clang/Frontend/CompilerInstance.h"
+#include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/FrontendTool/Utils.h"
 #include "clang/Lex/PreprocessorOptions.h"
 #include "gtest/gtest.h"
@@ -43,4 +44,58 @@
   EXPECT_TRUE(!IRBuffer.empty());
   EXPECT_TRUE(StringRef(IRBuffer.data()).startswith("BC"));
 }
+
+TEST(FrontendOutputTests, TestVerboseOutputStreamShared) {
+  auto Invocation = std::make_shared();
+  Invocation->getPreprocessorOpts().addRemappedFile(
+  "test.cc", MemoryBuffer::getMemBuffer("invalid").release());
+  Invocation->getFrontendOpts().Inputs.push_back(
+  FrontendInputFile("test.cc", Language::CXX));
+  Invocation->getFrontendOpts().ProgramAction = EmitBC;
+  Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
+  CompilerInstance Compiler;
+
+  std::string VerboseBuffer;
+  raw_string_ostream VerboseStream(VerboseBuffer);
+
+  Compiler.setInvocation(std::move(Invocation));
+  IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
+  Compiler.createDiagnostics(
+  new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
+  Compiler.setVerboseOutputStream(VerboseStream);
+
+  bool Success = ExecuteCompilerInvocation(&Compiler);
+  EXPECT_FALSE(Success);
+  EXPECT_TRUE(!VerboseStream.str().empty());
+  EXPECT_TRUE(StringRef(VerboseBuffer.data()).contains("errors generated"));
+}
+
+TEST(FrontendOutputTests, TestVerboseOutputStreamOwned) {
+  std::string VerboseBuffer;
+  bool Success;
+  {
+auto Invocation = std::make_shared();
+Invocation->getPreprocessorOpts().addRemappedFile(
+"test.cc", MemoryBuffer::getMemBuffer("invalid").release());
+Invocation->getFrontendOpts().Inputs.push_back(
+FrontendInputFile("test.cc", Language::CXX));
+Invocation->getFrontendOpts().ProgramAction = EmitBC;
+Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
+CompilerInstance Compiler;
+
+std::unique_ptr VerboseStream =
+std::make_unique(VerboseBuffer);
+
+Compiler.setInvocation(std::move(Invocation));
+IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions();
+Compiler.createDiagnostics(
+new TextDiagnosticPrinter(llvm::nulls(), &*DiagOpts), true);
+Compiler.setVerboseOutputStream(std::move(VerboseStream));
+
+Success = ExecuteCompilerInvocation(&Compiler);
+  }
+  EXPECT_FALSE(Success);
+  EXPECT_TRUE(!VerboseBuffer.empty());
+  EXPECT_TRUE(StringRef(VerboseBuffer.data()).contains("errors generated"));
+}
 }
Index: lib/Frontend/CompilerInstance.cpp
===
--- lib/Frontend/CompilerInstance.cpp
+++ lib/Frontend/CompilerInstance.cpp
@@ -86,6 +86,16 @@
   Diagnostics = Value;
 }
 
+void CompilerInstance::setVerboseOutputStream(raw_ostream &Value) {
+  OwnedVerboseOutputStream.release();
+  VerboseOutputStream = &Value;
+}
+
+void CompilerInstance::setVerboseOutputStream(std::unique_ptr Value) {
+  OwnedVerboseOutputStream.swap(Value);
+  VerboseOutputStream = OwnedVerboseOutputStream.get();
+}
+
 void CompilerInstance::setTarget(TargetInfo *Value) { Target = Value; }
 void CompilerInstance::setAuxTarget(TargetInfo *Value) { AuxTarget = Value; }
 
@@ -897,9 +907,7 @@
   // DesiredStackSpace available.
   noteBottomOfStack();
 
-  // FIXME: Take this as an argument, once all the APIs we used have moved to
-  // taking it as an input instead of hard-coding llvm::errs.
-  raw_ostream &OS = llvm::errs();
+  raw_ostream &OS = getVerboseOutputStream();
 
   if (!Act.PrepareToExecute(*this))
 return false;
Index: include/clang/Frontend/CompilerInstance.h
===
--- include/clang/Frontend/CompilerInstance.h
+++ include/clang/Frontend/CompilerInstance.h
@@ -155,6 +155,12 @@
   /// One or more modules failed to build.
   bool ModuleBuildFailed = false;
 
+  /// The stream for verbose output if owned, otherwise nullptr.
+  std::unique_ptr OwnedVerboseOutputStream;
+
+  /// The stream for verbose output.
+  raw_ostream *VerboseOutputStream = &llvm::errs();
+
   /// Holds information about the output file.
   ///
   /// If TempFilename is not empty we must rename it to Filename at the end.
@@ -217,9 +223,6 @@
   /// \param Act - The action to execute.
   /// \return - True on success.
   //
-  // FIXME: This function should 

[PATCH] D54823: [analyzer][MallocChecker][NFC] Document and reorganize some functions

2019-09-20 Thread Kristóf Umann via Phabricator via cfe-commits
Szelethus added a comment.

Welp, windows builtbots broke again. I'll try to see whats wrong with undef 
sanitizer, but fear this will end up in a revert.

http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/19769/steps/test-check-all/logs/stdio


Repository:
  rL LLVM

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

https://reviews.llvm.org/D54823



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67837: [CUDA][HIP] Fix assertion in Sema::markKnownEmitted with -fopenmp

2019-09-20 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl updated this revision to Diff 221097.
yaxunl added a comment.

reuse the call tree.


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

https://reviews.llvm.org/D67837

Files:
  lib/Sema/Sema.cpp
  test/SemaCUDA/openmp-static-func.cu


Index: test/SemaCUDA/openmp-static-func.cu
===
--- /dev/null
+++ test/SemaCUDA/openmp-static-func.cu
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
+// RUN:-verify -fopenmp %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
+// RUN:-verify -fopenmp -x hip %s
+// expected-no-diagnostics
+
+// Tests there is no assertion in Sema::markKnownEmitted when fopenmp is used
+// with CUDA/HIP host compilation.
+
+static void f() {}
+
+static void g() { f(); }
+
+static void h() { g(); }
Index: lib/Sema/Sema.cpp
===
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -1503,8 +1503,13 @@
 const llvm::function_ref IsKnownEmitted) {
   // Nothing to do if we already know that FD is emitted.
   if (IsKnownEmitted(S, OrigCallee)) {
-assert(!S.DeviceCallGraph.count(OrigCallee));
-return;
+// CUDA/HIP and OpenMP both put functions in DeviceCallGraph. A function
+// not sure to be emitted by one language may be found sure to be emitted
+// by another language. In that case, we will iterate the call graph and
+// mark all the callees. Otherwise, do nothing.
+auto Loc = S.DeviceCallGraph.find(OrigCallee);
+if (Loc == S.DeviceCallGraph.end())
+  return;
   }
 
   // We've just discovered that OrigCallee is known-emitted.  Walk our call
@@ -1520,8 +1525,6 @@
   Seen.insert(OrigCallee);
   while (!Worklist.empty()) {
 CallInfo C = Worklist.pop_back_val();
-assert(!IsKnownEmitted(S, C.Callee) &&
-   "Worklist should not contain known-emitted functions.");
 S.DeviceKnownEmittedFns[C.Callee] = {C.Caller, C.Loc};
 emitDeferredDiags(S, C.Callee, C.Caller);
 


Index: test/SemaCUDA/openmp-static-func.cu
===
--- /dev/null
+++ test/SemaCUDA/openmp-static-func.cu
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
+// RUN:-verify -fopenmp %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fsyntax-only \
+// RUN:-verify -fopenmp -x hip %s
+// expected-no-diagnostics
+
+// Tests there is no assertion in Sema::markKnownEmitted when fopenmp is used
+// with CUDA/HIP host compilation.
+
+static void f() {}
+
+static void g() { f(); }
+
+static void h() { g(); }
Index: lib/Sema/Sema.cpp
===
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -1503,8 +1503,13 @@
 const llvm::function_ref IsKnownEmitted) {
   // Nothing to do if we already know that FD is emitted.
   if (IsKnownEmitted(S, OrigCallee)) {
-assert(!S.DeviceCallGraph.count(OrigCallee));
-return;
+// CUDA/HIP and OpenMP both put functions in DeviceCallGraph. A function
+// not sure to be emitted by one language may be found sure to be emitted
+// by another language. In that case, we will iterate the call graph and
+// mark all the callees. Otherwise, do nothing.
+auto Loc = S.DeviceCallGraph.find(OrigCallee);
+if (Loc == S.DeviceCallGraph.end())
+  return;
   }
 
   // We've just discovered that OrigCallee is known-emitted.  Walk our call
@@ -1520,8 +1525,6 @@
   Seen.insert(OrigCallee);
   while (!Worklist.empty()) {
 CallInfo C = Worklist.pop_back_val();
-assert(!IsKnownEmitted(S, C.Callee) &&
-   "Worklist should not contain known-emitted functions.");
 S.DeviceKnownEmittedFns[C.Callee] = {C.Caller, C.Loc};
 emitDeferredDiags(S, C.Callee, C.Caller);
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45050: [clang-tidy] New checker for not null-terminated result caused by strlen(), size() or equal length

2019-09-20 Thread Csaba Dabis via Phabricator via cfe-commits
Charusso marked 3 inline comments as done.
Charusso added a comment.

Thanks!




Comment at: 
clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp:22-33
+constexpr llvm::StringLiteral FuncExprName = "entire-called-function-expr";
+constexpr llvm::StringLiteral CastExprName = "cast-expr";
+constexpr llvm::StringLiteral UnknownDestName = 
"destination-length-is-unknown";
+constexpr llvm::StringLiteral DestArrayTyName = "destination-is-array-type";
+constexpr llvm::StringLiteral DestVarDeclName = "destination-variable-decl";
+constexpr llvm::StringLiteral SrcVarDeclName = "source-variable-declaration";
+constexpr llvm::StringLiteral DestMallocExprName = "destination-malloc-expr";

alexfh wrote:
> Binding names are copied/read a lot (for memoization purposes, see 
> BoundNodesMap) during matching. It makes sense to make them shorter. Ideally 
> they should fit into the inline std::string buffer (15 characters in libc++ 
> on x86-64, https://gcc.godbolt.org/z/oNBghM).
Great explanation, thanks you!


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

https://reviews.llvm.org/D45050



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D45050: [clang-tidy] New checker for not null-terminated result caused by strlen(), size() or equal length

2019-09-20 Thread Csaba Dabis via Phabricator via cfe-commits
Charusso updated this revision to Diff 221096.
Charusso added a comment.

- Fix.


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

https://reviews.llvm.org/D45050

Files:
  clang-tools-extra/clang-tidy/bugprone/BugproneTidyModule.cpp
  clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt
  clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.cpp
  clang-tools-extra/clang-tidy/bugprone/NotNullTerminatedResultCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/bugprone-not-null-terminated-result.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/Inputs/bugprone-not-null-terminated-result/not-null-terminated-result-c.h
  
clang-tools-extra/test/clang-tidy/Inputs/bugprone-not-null-terminated-result/not-null-terminated-result-cxx.h
  
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-in-initialization-strlen.c
  
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-memcpy-before-safe.c
  
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-memcpy-safe-cxx.cpp
  
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-memcpy-safe-other.c
  
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-memcpy-safe.c
  clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-strlen.c
  
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-wcslen.cpp
  
clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-wmemcpy-safe-cxx.cpp

Index: clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-wmemcpy-safe-cxx.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/bugprone-not-null-terminated-result-wmemcpy-safe-cxx.cpp
@@ -0,0 +1,111 @@
+// RUN: %check_clang_tidy %s bugprone-not-null-terminated-result %t -- \
+// RUN: -- -std=c++11 -I %S/Inputs/bugprone-not-null-terminated-result
+
+#include "not-null-terminated-result-cxx.h"
+
+#define __STDC_LIB_EXT1__ 1
+#define __STDC_WANT_LIB_EXT1__ 1
+
+//===--===//
+// wmemcpy() - destination array tests
+//===--===//
+
+void bad_wmemcpy_known_dest(const wchar_t *src) {
+  wchar_t dest01[13];
+  wmemcpy(dest01, src, wcslen(src));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'wmemcpy' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: wchar_t dest01[14];
+  // CHECK-FIXES-NEXT: wcscpy_s(dest01, src);
+}
+
+void good_wmemcpy_known_dest(const wchar_t *src) {
+  wchar_t dst01[14];
+  wcscpy_s(dst01, src);
+}
+
+//===--===//
+// wmemcpy() - length tests
+//===--===//
+
+void bad_wmemcpy_full_source_length(const wchar_t *src) {
+  wchar_t dest20[13];
+  wmemcpy(dest20, src, wcslen(src));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'wmemcpy' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: wchar_t dest20[14];
+  // CHECK-FIXES-NEXT: wcscpy_s(dest20, src);
+}
+
+void good_wmemcpy_full_source_length(const wchar_t *src) {
+  wchar_t dst20[14];
+  wcscpy_s(dst20, src);
+}
+
+void bad_wmemcpy_partial_source_length(const wchar_t *src) {
+  wchar_t dest21[13];
+  wmemcpy(dest21, src, wcslen(src) - 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'wmemcpy' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: wchar_t dest21[14];
+  // CHECK-FIXES-NEXT: wcsncpy_s(dest21, src, wcslen(src) - 1);
+}
+
+void good_wmemcpy_partial_source_length(const wchar_t *src) {
+  wchar_t dst21[14];
+  wcsncpy_s(dst21, src, wcslen(src) - 1);
+}
+
+//===--===//
+// wmemcpy_s() - destination array tests
+//===--===//
+
+void bad_wmemcpy_s_unknown_dest(wchar_t *dest40, const wchar_t *src) {
+  wmemcpy_s(dest40, 13, src, wcslen(src));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'wmemcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: wcscpy_s(dest40, 13, src);
+}
+
+void good_wmemcpy_s_unknown_dest(wchar_t *dst40, const wchar_t *src) {
+  wcscpy_s(dst40, 13, src);
+}
+
+void bad_wmemcpy_s_known_dest(const wchar_t *src) {
+  wchar_t dest41[13];
+  wmemcpy_s(dest41, 13, src, wcslen(src));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the result from calling 'wmemcpy_s' is not null-terminated [bugprone-not-null-terminated-result]
+  // CHECK-FIXES: wchar_t dest41[14];
+  // CHECK-FIXES-NEXT: wcscpy_s(dest41, src);
+}
+
+void good_wmemcpy_s_known_dest(const wchar_t *src) {
+  wch

[PATCH] D67837: [CUDA][HIP] Fix assertion in Sema::markKnownEmitted with -fopenmp

2019-09-20 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl marked an inline comment as done.
yaxunl added inline comments.



Comment at: lib/Sema/Sema.cpp:1511
+if (Loc != S.DeviceCallGraph.end())
+  S.DeviceCallGraph.erase(Loc);
 return;

rjmccall wrote:
> There's an overload of `DenseMap::erase` that just takes a key value, so this 
> whole thing can be `S.DeviceCallGraph.erase(OrigCallee);`.
> 
> Why do we need to erase the entry instead of re-using it?  If the call graphs 
> are different for the two use-cases, is that conflict a problem for other 
> reasons?
I think you are right. we should reuse the call graph.


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

https://reviews.llvm.org/D67837



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67632: [libTooling] Introduce new library of source-code builders.

2019-09-20 Thread Yitzhak Mandelbaum via Phabricator via cfe-commits
ymandel updated this revision to Diff 221103.
ymandel added a comment.

converted builders to return optional


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67632

Files:
  clang/include/clang/Tooling/Refactoring/SourceCodeBuilders.h
  clang/lib/Tooling/Refactoring/CMakeLists.txt
  clang/lib/Tooling/Refactoring/SourceCodeBuilders.cpp
  clang/unittests/Tooling/CMakeLists.txt
  clang/unittests/Tooling/SourceCodeBuildersTest.cpp

Index: clang/unittests/Tooling/SourceCodeBuildersTest.cpp
===
--- /dev/null
+++ clang/unittests/Tooling/SourceCodeBuildersTest.cpp
@@ -0,0 +1,230 @@
+//===- unittest/Tooling/SourceCodeBuildersTest.cpp ===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "clang/Tooling/Refactoring/SourceCodeBuilders.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/Tooling.h"
+#include "llvm/Testing/Support/SupportHelpers.h"
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+
+using namespace clang;
+using namespace tooling;
+using namespace ast_matchers;
+
+namespace {
+using MatchResult = MatchFinder::MatchResult;
+using llvm::ValueIs;
+
+// Create a valid translation unit from a statement.
+static std::string wrapSnippet(StringRef StatementCode) {
+  return ("struct S { S(); S(int); int field; };\n"
+  "S operator+(const S &a, const S &b);\n"
+  "auto test_snippet = []{" +
+  StatementCode + "};")
+  .str();
+}
+
+static DeclarationMatcher wrapMatcher(const StatementMatcher &Matcher) {
+  return varDecl(hasName("test_snippet"),
+ hasDescendant(compoundStmt(hasAnySubstatement(Matcher;
+}
+
+struct TestMatch {
+  // The AST unit from which `result` is built. We bundle it because it backs
+  // the result. Users are not expected to access it.
+  std::unique_ptr AstUnit;
+  // The result to use in the test. References `ast_unit`.
+  MatchResult Result;
+};
+
+// Matches `Matcher` against the statement `StatementCode` and returns the
+// result. Handles putting the statement inside a function and modifying the
+// matcher correspondingly. `Matcher` should match one of the statements in
+// `StatementCode` exactly -- that is, produce exactly one match. However,
+// `StatementCode` may contain other statements not described by `Matcher`.
+static llvm::Optional matchStmt(StringRef StatementCode,
+   StatementMatcher Matcher) {
+  auto AstUnit = buildASTFromCode(wrapSnippet(StatementCode));
+  if (AstUnit == nullptr) {
+ADD_FAILURE() << "AST construction failed";
+return llvm::None;
+  }
+  ASTContext &Context = AstUnit->getASTContext();
+  auto Matches = ast_matchers::match(wrapMatcher(Matcher), Context);
+  // We expect a single, exact match for the statement.
+  if (Matches.size() != 1) {
+ADD_FAILURE() << "Wrong number of matches: " << Matches.size();
+return llvm::None;
+  }
+  return TestMatch{std::move(AstUnit), MatchResult(Matches[0], &Context)};
+}
+
+static void testPredicate(bool (*Pred)(const Expr &), StringRef Snippet,
+  bool Expected) {
+  auto StmtMatch = matchStmt(Snippet, expr().bind("expr"));
+  ASSERT_TRUE(StmtMatch) << "Snippet: " << Snippet;
+  EXPECT_EQ(Expected, Pred(*StmtMatch->Result.Nodes.getNodeAs("expr")))
+  << "Snippet: " << Snippet;
+}
+
+// Tests the predicate on the call argument, assuming `Snippet` is a function
+// call.
+static void testPredicateOnArg(bool (*Pred)(const Expr &), StringRef Snippet,
+   bool Expected) {
+  auto StmtMatch = matchStmt(
+  Snippet, expr(ignoringImplicit(callExpr(hasArgument(
+   0, ignoringElidableConstructorCall(expr().bind("arg")));
+  ASSERT_TRUE(StmtMatch) << "Snippet: " << Snippet;
+  EXPECT_EQ(Expected, Pred(*StmtMatch->Result.Nodes.getNodeAs("arg")))
+  << "Snippet: " << Snippet;
+}
+
+TEST(SourceCodeBuildersTest, needParensAfterUnaryOperator) {
+  testPredicate(needParensAfterUnaryOperator, "3 + 5;", true);
+  testPredicate(needParensAfterUnaryOperator, "true ? 3 : 5;", true);
+  testPredicate(needParensAfterUnaryOperator, "S(3) + S(5);", true);
+
+  testPredicate(needParensAfterUnaryOperator, "int x; x;", false);
+  testPredicate(needParensAfterUnaryOperator, "int(3.0);", false);
+  testPredicate(needParensAfterUnaryOperator, "void f(); f();", false);
+  testPredicate(needParensAfterUnaryOperator, "int a[3]; a[0];", false);
+  testPredicate(needParensAfterUnaryOperator, "S x; x.field;", false);
+  testPredicate(needParensAfterUnaryOperator, "int x = 1; --

[libunwind] r372427 - Unwind: avoid warning about unused typedef

2019-09-20 Thread Saleem Abdulrasool via cfe-commits
Author: compnerd
Date: Fri Sep 20 13:46:33 2019
New Revision: 372427

URL: http://llvm.org/viewvc/llvm-project?rev=372427&view=rev
Log:
Unwind: avoid warning about unused typedef

Move the definition of Elf_Addr typedef to the only place it is used, to avoid:

```
llvm-project/libunwind/src/AddressSpace.hpp:501:28: warning: unused typedef 
'Elf_Addr' [-Wunused-local-typedef]
```

when compiling for Android with _LIBUNWIND_ARM_EHABI defined and
_LIBUNWIND_SUPPORT_DWARF_UNWIND not defined.

Patch by Joel Klinghed!

Modified:
libunwind/trunk/src/AddressSpace.hpp

Modified: libunwind/trunk/src/AddressSpace.hpp
URL: 
http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/AddressSpace.hpp?rev=372427&r1=372426&r2=372427&view=diff
==
--- libunwind/trunk/src/AddressSpace.hpp (original)
+++ libunwind/trunk/src/AddressSpace.hpp Fri Sep 20 13:46:33 2019
@@ -497,9 +497,6 @@ inline bool LocalAddressSpace::findUnwin
 #if !defined(Elf_Phdr)
 typedef ElfW(Phdr) Elf_Phdr;
 #endif
-#if !defined(Elf_Addr) && defined(__ANDROID__)
-typedef ElfW(Addr) Elf_Addr;
-#endif
 
  #if defined(_LIBUNWIND_SUPPORT_DWARF_UNWIND)
   #if !defined(_LIBUNWIND_SUPPORT_DWARF_INDEX)
@@ -507,6 +504,9 @@ inline bool LocalAddressSpace::findUnwin
   #endif
 size_t object_length;
 #if defined(__ANDROID__)
+#if !defined(Elf_Addr)
+typedef ElfW(Addr) Elf_Addr;
+#endif
 Elf_Addr image_base =
 pinfo->dlpi_phnum
 ? reinterpret_cast(pinfo->dlpi_phdr) -


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67865: [clang-tidy] Finds uses of OSRead* calls on macOS that may mask unexpected behavior due to unaligned reads

2019-09-20 Thread Dave MacLachlan via Phabricator via cfe-commits
dmaclach created this revision.
dmaclach added a reviewer: alexfh.
Herald added subscribers: cfe-commits, kristof.beyls, xazax.hun, mgorny.
Herald added a project: clang.

We ran into a problem in protocol buffers recently when compiling with Xcode 11 
that caused crashes on 32 bit ARM architectures due to undefined behavior 
caused by OSRead* calls in OSByteOrder.h when reading unaligned addresses.

These potential errors can easily be fixed by replacing the OSRead* call with a 
memcpy and then a OSSwap{Big|Little}ToHostInt{16|32|64}.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D67865

Files:
  clang-tidy/objc/AvoidOSReadCheck.cpp
  clang-tidy/objc/AvoidOSReadCheck.h
  clang-tidy/objc/CMakeLists.txt
  clang-tidy/objc/ObjCTidyModule.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/objc-avoid-osread.rst
  test/clang-tidy/objc-avoid-osread.m

Index: test/clang-tidy/objc-avoid-osread.m
===
--- /dev/null
+++ test/clang-tidy/objc-avoid-osread.m
@@ -0,0 +1,35 @@
+// RUN: %check_clang_tidy %s objc-avoid-osread %t
+
+void f() {
+  const char *buff = "";
+  OSReadBigInt(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadBigInt(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadLittleInt(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadBigInt16(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadBigInt32(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadBigInt64(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadLittleInt16(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadLittleInt32(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadLittleInt64(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadSwapInt16(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadSwapInt32(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  OSReadSwapInt64(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  _OSReadInt16(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  _OSReadInt32(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+  _OSReadInt64(buff, 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use memcpy and OSSwap{Big|Little}ToHostInt{16|32|64} instead of OSRead* calls to avoid potential unaligned read issues [objc-avoid-osread]
+}
Index: docs/clang-tidy/checks/objc-avoid-osread.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/objc-avoid-osread.rst
@@ -0,0 +1,36 @@
+.. title:: clang-tidy - objc-avoid-osread
+
+objc-avoid-osread
+=
+
+Finds usages of ``OSRead{Big|Little}Int{16|32|64}`` and associated functions which
+should be avoided due to potential unaligned read problems.
+
+This check will detect following function invocations:
+
+- ``OSReadBigInt``
+- ``OSReadLittleInt``
+- ``OSReadBigInt16``
+- ``OSReadBigInt32``
+- ``OSReadBigInt64``

[PATCH] D67509: [CUDA][HIP] Fix hostness of defaulted constructor

2019-09-20 Thread Artem Belevich via Phabricator via cfe-commits
tra added a comment.

Looks like CUDA test-suite is triggering the assertion added by this patch:

http://lab.llvm.org:8011/builders/clang-cuda-build/builds/37301/steps/ninja%20build%20simple%20CUDA%20tests/logs/stdio


Repository:
  rL LLVM

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

https://reviews.llvm.org/D67509



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67774: [Mangle] Add flag to asm labels to disable global prefixing

2019-09-20 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: clang/include/clang/Basic/Attr.td:725
   let Spellings = [Keyword<"asm">, Keyword<"__asm__">];
-  let Args = [StringArgument<"Label">];
+  let Args = [StringArgument<"Label">, BoolArgument<"LiteralLabel">];
   let SemaHandler = 0;

Does this actually change how it can be written in source?  I think it might be 
a good idea to do that in the long run, but let's not in this patch.

Also something really needs to document what this is actually for.



Comment at: clang/lib/AST/Mangle.cpp:137
+(!Source || Source->UseGlobalPrefixInAsmLabelMangle()))
   Out << '\01'; // LLVM IR Marker for __asm("foo")
 

rjmccall wrote:
> This is one of those bugs where looking at the code really reveals a lot of 
> problematic behavior.
> 
> `AsmLabelAttr` is generally assumed to carry a literal label, i.e. it should 
> not have the global prefix added to it.  We should not be changing that 
> assumption globally just based on whether an `ExternalASTSource` has been set 
> up; that's going to break in any sort of non-uniform situation, e.g. if an 
> LLDB user writes a declaration with an asm label, or if we import a Clang 
> module where a declaration has an asm label.  Either `ExternalASTSource`s 
> should be putting the real (prefixed) symbol name in the `AsmLabelAttr`, or 
> they should be making `AsmLabelAttr`s that are different somehow, e.g. by 
> giving `AsmLabelAttr` a flag (which doesn't need to be spellable in the 
> source language) saying whether the label is literal or subject to global 
> prefixing.
> 
> Separately, it seems to me that if the `AsmLabelAttr` is literal but the 
> label happens to include the global prefix, we should strip the prefix from 
> the label and not add a `\01` so that we get a consistent symbol name in LLVM.
Please check for whether the label is literal first before pulling out the 
global prefix.



Comment at: clang/lib/Sema/SemaDecl.cpp:2770
+  assert(OldA->getLiteralLabel() == NewA->getLiteralLabel() &&
+ "Redeclaration of asm label changes label kind");
   if (OldA->getLabel() != NewA->getLabel()) {

This is definitely not a safe assumption; for one, we might eventually allow 
this to be spelled in source, and for another, you can redeclare something from 
the global context in LLDB and therefore get this kind of mismatch.  Anyway, I 
don't think you need the assumption here; just add a method to `AsmLabelAttr` 
that checks for equality in a way that compensates for the 
inclusion/suppression of the global prefix.


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

https://reviews.llvm.org/D67774



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67837: [CUDA][HIP] Fix assertion in Sema::markKnownEmitted with -fopenmp

2019-09-20 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: lib/Sema/Sema.cpp:1511
+if (Loc != S.DeviceCallGraph.end())
+  S.DeviceCallGraph.erase(Loc);
 return;

yaxunl wrote:
> rjmccall wrote:
> > There's an overload of `DenseMap::erase` that just takes a key value, so 
> > this whole thing can be `S.DeviceCallGraph.erase(OrigCallee);`.
> > 
> > Why do we need to erase the entry instead of re-using it?  If the call 
> > graphs are different for the two use-cases, is that conflict a problem for 
> > other reasons?
> I think you are right. we should reuse the call graph.
Okay.  I believe DenseMap has a `count` that tells you how many entries there 
are for a key.


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

https://reviews.llvm.org/D67837



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372436 - [SystemZ] Support z15 processor name

2019-09-20 Thread Ulrich Weigand via cfe-commits
Author: uweigand
Date: Fri Sep 20 16:06:03 2019
New Revision: 372436

URL: http://llvm.org/viewvc/llvm-project?rev=372436&view=rev
Log:
[SystemZ] Support z15 processor name

The recently announced IBM z15 processor implements the architecture
already supported as "arch13" in LLVM.  This patch adds support for
"z15" as an alternate architecture name for arch13.

Corrsponding LLVM support was committed as rev. 372435.


Modified:
cfe/trunk/lib/Basic/Targets/SystemZ.cpp
cfe/trunk/test/CodeGen/builtins-systemz-vector3-error.c
cfe/trunk/test/CodeGen/builtins-systemz-vector3.c
cfe/trunk/test/CodeGen/builtins-systemz-zvector3-error.c
cfe/trunk/test/CodeGen/builtins-systemz-zvector3.c
cfe/trunk/test/CodeGen/systemz-abi-vector.c
cfe/trunk/test/CodeGen/systemz-abi.c
cfe/trunk/test/CodeGen/target-data.c
cfe/trunk/test/Driver/systemz-march.c
cfe/trunk/test/Misc/target-invalid-cpu-note.c
cfe/trunk/test/Preprocessor/predefined-arch-macros.c

Modified: cfe/trunk/lib/Basic/Targets/SystemZ.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/SystemZ.cpp?rev=372436&r1=372435&r2=372436&view=diff
==
--- cfe/trunk/lib/Basic/Targets/SystemZ.cpp (original)
+++ cfe/trunk/lib/Basic/Targets/SystemZ.cpp Fri Sep 20 16:06:03 2019
@@ -92,7 +92,7 @@ static constexpr ISANameRevision ISARevi
   {{"arch10"}, 10}, {{"zEC12"}, 10},
   {{"arch11"}, 11}, {{"z13"}, 11},
   {{"arch12"}, 12}, {{"z14"}, 12},
-  {{"arch13"}, 13},
+  {{"arch13"}, 13}, {{"z15"}, 13}
 };
 
 int SystemZTargetInfo::getISARevision(StringRef Name) const {

Modified: cfe/trunk/test/CodeGen/builtins-systemz-vector3-error.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins-systemz-vector3-error.c?rev=372436&r1=372435&r2=372436&view=diff
==
--- cfe/trunk/test/CodeGen/builtins-systemz-vector3-error.c (original)
+++ cfe/trunk/test/CodeGen/builtins-systemz-vector3-error.c Fri Sep 20 16:06:03 
2019
@@ -1,5 +1,5 @@
 // REQUIRES: systemz-registered-target
-// RUN: %clang_cc1 -target-cpu arch13 -triple s390x-unknown-unknown \
+// RUN: %clang_cc1 -target-cpu z15 -triple s390x-unknown-unknown \
 // RUN: -Wall -Wno-unused -Werror -fsyntax-only -verify %s
 
 typedef __attribute__((vector_size(16))) signed char vec_schar;

Modified: cfe/trunk/test/CodeGen/builtins-systemz-vector3.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins-systemz-vector3.c?rev=372436&r1=372435&r2=372436&view=diff
==
--- cfe/trunk/test/CodeGen/builtins-systemz-vector3.c (original)
+++ cfe/trunk/test/CodeGen/builtins-systemz-vector3.c Fri Sep 20 16:06:03 2019
@@ -1,5 +1,5 @@
 // REQUIRES: systemz-registered-target
-// RUN: %clang_cc1 -target-cpu arch13 -triple s390x-ibm-linux 
-flax-vector-conversions=none \
+// RUN: %clang_cc1 -target-cpu z15 -triple s390x-ibm-linux 
-flax-vector-conversions=none \
 // RUN: -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s
 
 typedef __attribute__((vector_size(16))) signed char vec_schar;

Modified: cfe/trunk/test/CodeGen/builtins-systemz-zvector3-error.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins-systemz-zvector3-error.c?rev=372436&r1=372435&r2=372436&view=diff
==
--- cfe/trunk/test/CodeGen/builtins-systemz-zvector3-error.c (original)
+++ cfe/trunk/test/CodeGen/builtins-systemz-zvector3-error.c Fri Sep 20 
16:06:03 2019
@@ -1,5 +1,5 @@
 // REQUIRES: systemz-registered-target
-// RUN: %clang_cc1 -target-cpu arch13 -triple s390x-linux-gnu \
+// RUN: %clang_cc1 -target-cpu z15 -triple s390x-linux-gnu \
 // RUN: -fzvector -flax-vector-conversions=none \
 // RUN: -Wall -Wno-unused -Werror -fsyntax-only -verify %s
 

Modified: cfe/trunk/test/CodeGen/builtins-systemz-zvector3.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/builtins-systemz-zvector3.c?rev=372436&r1=372435&r2=372436&view=diff
==
--- cfe/trunk/test/CodeGen/builtins-systemz-zvector3.c (original)
+++ cfe/trunk/test/CodeGen/builtins-systemz-zvector3.c Fri Sep 20 16:06:03 2019
@@ -1,8 +1,8 @@
 // REQUIRES: systemz-registered-target
-// RUN: %clang_cc1 -target-cpu arch13 -triple s390x-linux-gnu \
+// RUN: %clang_cc1 -target-cpu z15 -triple s390x-linux-gnu \
 // RUN: -O -fzvector -flax-vector-conversions=none \
 // RUN: -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s
-// RUN: %clang_cc1 -target-cpu arch13 -triple s390x-linux-gnu \
+// RUN: %clang_cc1 -target-cpu z15 -triple s390x-linux-gnu \
 // RUN: -O -fzvector -flax-vector-conversions=none \
 // RUN: -Wall -Wno-unused -Werror -S %s -o - | FileCheck %s 
--check-prefix=CHECK-ASM
 

Modified: cfe/trunk/test/CodeGen/systemz-

r372437 - Fix assertion failure when constant evaluation of a switch jumps over an

2019-09-20 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Fri Sep 20 16:08:59 2019
New Revision: 372437

URL: http://llvm.org/viewvc/llvm-project?rev=372437&view=rev
Log:
Fix assertion failure when constant evaluation of a switch jumps over an
uninitialized variable in an init-statement of a 'for' or 'if'.

Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=372437&r1=372436&r2=372437&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Sep 20 16:08:59 2019
@@ -4131,6 +4131,21 @@ static EvalStmtResult EvaluateStmt(StmtR
   // preceded by our switch label.
   BlockScopeRAII Scope(Info);
 
+  // Step into the init statement in case it brings an (uninitialized)
+  // variable into scope.
+  if (const Stmt *Init = IS->getInit()) {
+EvalStmtResult ESR = EvaluateStmt(Result, Info, Init, Case);
+if (ESR != ESR_CaseNotFound) {
+  assert(ESR != ESR_Succeeded);
+  return ESR;
+}
+  }
+
+  // Condition variable must be initialized if it exists.
+  // FIXME: We can skip evaluating the body if there's a condition
+  // variable, as there can't be any case labels within it.
+  // (The same is true for 'for' statements.)
+
   EvalStmtResult ESR = EvaluateStmt(Result, Info, IS->getThen(), Case);
   if (ESR != ESR_CaseNotFound || !IS->getElse())
 return ESR;
@@ -4147,6 +4162,18 @@ static EvalStmtResult EvaluateStmt(StmtR
 
 case Stmt::ForStmtClass: {
   const ForStmt *FS = cast(S);
+  BlockScopeRAII Scope(Info);
+
+  // Step into the init statement in case it brings an (uninitialized)
+  // variable into scope.
+  if (const Stmt *Init = FS->getInit()) {
+EvalStmtResult ESR = EvaluateStmt(Result, Info, Init, Case);
+if (ESR != ESR_CaseNotFound) {
+  assert(ESR != ESR_Succeeded);
+  return ESR;
+}
+  }
+
   EvalStmtResult ESR =
   EvaluateLoopBody(Result, Info, FS->getBody(), Case);
   if (ESR != ESR_Continue)

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp?rev=372437&r1=372436&r2=372437&view=diff
==
--- cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp Fri Sep 20 16:08:59 
2019
@@ -620,4 +620,17 @@ namespace Uninit {
   constexpr int s1 = switch_var(1);
   constexpr int s2 = switch_var(2);
   static_assert(s1 == 1 && s2 == 2);
+
+  constexpr bool switch_into_init_stmt() {
+switch (1) {
+  if (int n; false) {
+for (int m; false;) {
+case 1:
+  n = m = 1;
+  return n == 1 && m == 1;
+}
+  }
+}
+  }
+  static_assert(switch_into_init_stmt());
 }


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372438 - Remove outdated FIXME.

2019-09-20 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Fri Sep 20 16:12:51 2019
New Revision: 372438

URL: http://llvm.org/viewvc/llvm-project?rev=372438&view=rev
Log:
Remove outdated FIXME.

Modified:
cfe/trunk/lib/AST/ExprConstant.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=372438&r1=372437&r2=372438&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Sep 20 16:12:51 2019
@@ -4102,10 +4102,6 @@ static EvalStmtResult EvaluateStmt(StmtR
   // If we're hunting down a 'case' or 'default' label, recurse through
   // substatements until we hit the label.
   if (Case) {
-// FIXME: We don't start the lifetime of objects whose initialization we
-// jump over. However, such objects must be of class type with a trivial
-// default constructor that initialize all subobjects, so must be empty,
-// so this almost never matters.
 switch (S->getStmtClass()) {
 case Stmt::CompoundStmtClass:
   // FIXME: Precompute which substatement of a compound statement we


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67509: [CUDA][HIP] Fix hostness of defaulted constructor

2019-09-20 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl added a comment.

In D67509#1677528 , @tra wrote:

> Looks like CUDA test-suite is triggering the assertion added by this patch:
>
> http://lab.llvm.org:8011/builders/clang-cuda-build/builds/37301/steps/ninja%20build%20simple%20CUDA%20tests/logs/stdio


I am taking a look.


Repository:
  rL LLVM

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

https://reviews.llvm.org/D67509



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D65917: [clang-tidy] Added check for the Google style guide's category method naming rule.

2019-09-20 Thread David Gatwood via Phabricator via cfe-commits
dgatwood updated this revision to Diff 221128.
dgatwood marked 5 inline comments as done.
dgatwood added a comment.

Renamed to ExemptClassPrefixes.


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

https://reviews.llvm.org/D65917

Files:
  clang-tools-extra/clang-tidy/google/CMakeLists.txt
  clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
  clang-tools-extra/clang-tidy/google/RequireCategoryMethodPrefixesCheck.cpp
  clang-tools-extra/clang-tidy/google/RequireCategoryMethodPrefixesCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/google-objc-require-category-method-prefixes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/google-objc-require-category-method-prefixes.m

Index: clang-tools-extra/test/clang-tidy/google-objc-require-category-method-prefixes.m
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/google-objc-require-category-method-prefixes.m
@@ -0,0 +1,35 @@
+// RUN: %check_clang_tidy %s google-objc-require-category-method-prefixes %t -config="{CheckOptions: [{key: google-objc-require-category-method-prefixes.ExpectedPrefixes, value: GMO}]}"
+
+@class NSString;
+
+@interface NSURL
++ (nullable instancetype)URLWithString:(NSString *)URLString;
++ (instancetype)alloc;
+- (instancetype)init;
+@end
+
+@interface NSURL (CustomExtension)
+
+- (void)unprefixedMethod;
+- (void)unprefixed;
+- (void)justprefixed_;
+
+@end
+
+// CHECK-MESSAGES: :[[@LINE-6]]:1: warning: the category method 'unprefixedMethod' is not properly prefixed [google-objc-require-category-method-prefixes]
+// CHECK-MESSAGES: :[[@LINE-6]]:1: warning: the category method 'unprefixed' is not properly prefixed [google-objc-require-category-method-prefixes]
+// CHECK-MESSAGES: :[[@LINE-6]]:1: warning: the category method 'justprefixed_' is not properly prefixed [google-objc-require-category-method-prefixes]
+
+@interface NSURL (CustomExtension2)
+- (void)gmo_prefixedMethod;
+@end
+
+@interface GMOURL
++ (nullable instancetype)URLWithString:(NSString *)URLString;
++ (instancetype)alloc;
+- (instancetype)init;
+@end
+
+@interface GMOURL (CustomExtension3)
+- (void)unprefixedMethodInClassWithExpectedPrefix;
+@end
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -230,6 +230,7 @@
google-objc-avoid-throwing-exception
google-objc-function-naming
google-objc-global-variable-declaration
+   google-objc-require-category-method-prefixes
google-readability-avoid-underscore-in-googletest-name
google-readability-braces-around-statements (redirects to readability-braces-around-statements) 
google-readability-casting
Index: clang-tools-extra/docs/clang-tidy/checks/google-objc-require-category-method-prefixes.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/google-objc-require-category-method-prefixes.rst
@@ -0,0 +1,45 @@
+.. title:: clang-tidy - google-objc-require-category-method-prefixes
+
+google-objc-require-category-method-prefixes
+
+
+Warns when Objective-C category method names are not properly prefixed (e.g.
+``gmo_methodName``) unless the category is extending a class with an
+expected prefix (configurable).
+
+The Google Objective-C style guide requires
+`prefixes for methods http://go/objc-style#Category_Names`_ in categories on
+classes that you don't control (for example, categories on Apple or third-party
+framework classes or classes created by other teams) to prevent name collisions
+when those frameworks are updated.
+
+This checker ensures that all methods in categories have some sort of prefix
+(e.g. ``gmo_``).  It allows you to provide a list of expected three-letter
+prefixes specific to your project, and ignores non-prefixed methods in
+categories on classes whose names start with any of those prefixes.
+
+For example, the following code sample is a properly prefixed method on a
+non-owned class (``NSObject``):
+
+.. code-block:: objc
+  @interface NSObject (QEDMyCategory)
+  - (BOOL)qed_myCustomMethod;
+  @end
+
+If you specify ``QED`` as an expected three-letter prefix, the following code
+sample is also allowed:
+
+.. code-block:: objc
+
+  @interface QEDMyClass (MyCategory)
+  - (BOOL)myCustomMethod;
+  @end
+
+Options
+---
+
+.. option:: ExemptClassPrefixes
+
+   A semicolon-delimited list of class name prefixes.  Methods in categories
+   that extend classes whose names begin with any of these prefixes are exempt
+   from the method name prefixing requirement.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes

[PATCH] D65917: [clang-tidy] Added check for the Google style guide's category method naming rule.

2019-09-20 Thread David Gatwood via Phabricator via cfe-commits
dgatwood added inline comments.



Comment at: 
clang-tools-extra/clang-tidy/google/RequireCategoryMethodPrefixesCheck.cpp:23
+  Finder->addMatcher(objcMethodDecl(hasDeclContext(
+  objcCategoryDecl())).bind(CustomCategoryMethodIdentifier), this);
+}

stephanemoore wrote:
> Technically category method prefixing is only strictly enforced on classes 
> that are shared:
> "If a class is not shared with other projects, categories extending it may 
> omit name prefixes and method name prefixes."
> https://github.com/google/styleguide/blob/gh-pages/objcguide.md#category-naming
> 
> With that in mind, perhaps we should match on categories on classes that 
> extend classes that are declared in system headers? I think you can 
> accomplish that by adding a custom inner matcher in `objcCategoryDecl` which 
> pulls out the Objective-C interface using 
> [clang::ObjCCategoryDecl::getClassInterface](https://clang.llvm.org/doxygen/classclang_1_1ObjCCategoryDecl.html#acdb14eeca277cfa745a4e8e842312008)
>  and then add `isExpansionInSystemHeader` as an inner matcher on the custom 
> inner matcher. WDYT? Let me know if you need help putting together.
Requiring users to specify which classes should be covered by this checker 
doesn't scale well.  System classes are a tiny fraction of the shared code that 
we bring in.  Proto classes alone probably outnumber system framework classes 
10:1, plus all the shared code from other internal framework teams.  A list of 
every shared class that we bring in would be massive, and generating it 
programmatically would be relatively expensive.  The same problem exists for a 
list of prefixes to protect.

Also with that approach, a mistake by a person or script that maintains such a 
list would result in **not** getting warnings.  Silent failures are the worst 
kind of failure, because you don't even know that something is going wrong.  By 
contrast, if you require the user to specify a list of prefixes to ignore, as 
this patch does, then any mistake by someone maintaining the lest results in 
getting **extra** warnings, which makes it obvious that something is wrong and 
needs to be fixed.

I realize that ostensibly a team could own some code that is also shared, and 
it could have the same prefix as their app.  But there's no real reason to care 
about that case.  After all, if someone changes the shared code and it breaks 
the category, it's the same team, so their tests should catch the breakage, 
unlike changes made by some far-flung team on the other side of the world.  
Also, if they break their own code, they also have permission to fix that 
breakage without additional approvals.  So that edge case is largely academic; 
if anybody asks for a way to not ignore specific classes that have an exempt 
prefix, we can certainly add that feature later pretty easily, but I really 
doubt anybody would bother to use it.  :-)


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

https://reviews.llvm.org/D65917



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D65917: [clang-tidy] Added check for the Google style guide's category method naming rule.

2019-09-20 Thread David Gatwood via Phabricator via cfe-commits
dgatwood updated this revision to Diff 221142.
dgatwood added a comment.

Updated the configuration key in the test file.


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

https://reviews.llvm.org/D65917

Files:
  clang-tools-extra/clang-tidy/google/CMakeLists.txt
  clang-tools-extra/clang-tidy/google/GoogleTidyModule.cpp
  clang-tools-extra/clang-tidy/google/RequireCategoryMethodPrefixesCheck.cpp
  clang-tools-extra/clang-tidy/google/RequireCategoryMethodPrefixesCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/docs/clang-tidy/checks/google-objc-require-category-method-prefixes.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/test/clang-tidy/google-objc-require-category-method-prefixes.m

Index: clang-tools-extra/test/clang-tidy/google-objc-require-category-method-prefixes.m
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/google-objc-require-category-method-prefixes.m
@@ -0,0 +1,35 @@
+// RUN: %check_clang_tidy %s google-objc-require-category-method-prefixes %t -config="{CheckOptions: [{key: google-objc-require-category-method-prefixes.ExemptClassPrefixes, value: GMO}]}"
+
+@class NSString;
+
+@interface NSURL
++ (nullable instancetype)URLWithString:(NSString *)URLString;
++ (instancetype)alloc;
+- (instancetype)init;
+@end
+
+@interface NSURL (CustomExtension)
+
+- (void)unprefixedMethod;
+- (void)unprefixed;
+- (void)justprefixed_;
+
+@end
+
+// CHECK-MESSAGES: :[[@LINE-6]]:1: warning: the category method 'unprefixedMethod' is not properly prefixed [google-objc-require-category-method-prefixes]
+// CHECK-MESSAGES: :[[@LINE-6]]:1: warning: the category method 'unprefixed' is not properly prefixed [google-objc-require-category-method-prefixes]
+// CHECK-MESSAGES: :[[@LINE-6]]:1: warning: the category method 'justprefixed_' is not properly prefixed [google-objc-require-category-method-prefixes]
+
+@interface NSURL (CustomExtension2)
+- (void)gmo_prefixedMethod;
+@end
+
+@interface GMOURL
++ (nullable instancetype)URLWithString:(NSString *)URLString;
++ (instancetype)alloc;
+- (instancetype)init;
+@end
+
+@interface GMOURL (CustomExtension3)
+- (void)unprefixedMethodInClassWithExpectedPrefix;
+@end
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -230,6 +230,7 @@
google-objc-avoid-throwing-exception
google-objc-function-naming
google-objc-global-variable-declaration
+   google-objc-require-category-method-prefixes
google-readability-avoid-underscore-in-googletest-name
google-readability-braces-around-statements (redirects to readability-braces-around-statements) 
google-readability-casting
Index: clang-tools-extra/docs/clang-tidy/checks/google-objc-require-category-method-prefixes.rst
===
--- /dev/null
+++ clang-tools-extra/docs/clang-tidy/checks/google-objc-require-category-method-prefixes.rst
@@ -0,0 +1,45 @@
+.. title:: clang-tidy - google-objc-require-category-method-prefixes
+
+google-objc-require-category-method-prefixes
+
+
+Warns when Objective-C category method names are not properly prefixed (e.g.
+``gmo_methodName``) unless the category is extending a class with an
+expected prefix (configurable).
+
+The Google Objective-C style guide requires
+`prefixes for methods http://go/objc-style#Category_Names`_ in categories on
+classes that you don't control (for example, categories on Apple or third-party
+framework classes or classes created by other teams) to prevent name collisions
+when those frameworks are updated.
+
+This checker ensures that all methods in categories have some sort of prefix
+(e.g. ``gmo_``).  It allows you to provide a list of expected three-letter
+prefixes specific to your project, and ignores non-prefixed methods in
+categories on classes whose names start with any of those prefixes.
+
+For example, the following code sample is a properly prefixed method on a
+non-owned class (``NSObject``):
+
+.. code-block:: objc
+  @interface NSObject (QEDMyCategory)
+  - (BOOL)qed_myCustomMethod;
+  @end
+
+If you specify ``QED`` as an expected three-letter prefix, the following code
+sample is also allowed:
+
+.. code-block:: objc
+
+  @interface QEDMyClass (MyCategory)
+  - (BOOL)myCustomMethod;
+  @end
+
+Options
+---
+
+.. option:: ExemptClassPrefixes
+
+   A semicolon-delimited list of class name prefixes.  Methods in categories
+   that extend classes whose names begin with any of these prefixes are exempt
+   from the method name prefixing requirement.
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-ext

[PATCH] D51905: Front-end of the implementation of the interleaving algorithm

2019-09-20 Thread Zhaomo Yang via Phabricator via cfe-commits
zhaomo updated this revision to Diff 221140.
zhaomo added a comment.

In this new patch,  I added a "level" field to type metadata when vtable 
interleaving is enabled.
Currently type metadata is a (byte offset, type) pair. However, suppose T1 and 
T2 are compatible with the same offset of a vtable, the interleaving pass 
cannot always determine which type is the less derived one because T1 and T2 
may have the same number of compatible vtables. An observation is that types 
that are compatible with the same address point like T1 and T2 form a linear 
inheritance hierarchy. Based on this, I added a third field to the type 
metadata representing the level of the type in the linear type hierarchy. 
all-vtables' level value is 1 and any other type's level is greater than 1. The 
more derived a type is, the higher the level is.


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

https://reviews.llvm.org/D51905

Files:
  clang/include/clang/AST/VTableBuilder.h
  clang/include/clang/Basic/ABI.h
  clang/include/clang/Basic/CodeGenOptions.def
  clang/include/clang/Driver/CC1Options.td
  clang/lib/AST/VTableBuilder.cpp
  clang/lib/CodeGen/CGCXXABI.h
  clang/lib/CodeGen/CGClass.cpp
  clang/lib/CodeGen/CGVTables.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/CodeGen/CodeGenModule.cpp
  clang/lib/CodeGen/CodeGenModule.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/CodeGen/MicrosoftCXXABI.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/test/CodeGen/tbaa-for-vptr.cpp
  clang/test/CodeGenCXX/alignment.cpp
  clang/test/CodeGenCXX/arm.cpp
  clang/test/CodeGenCXX/cfi-cross-dso.cpp
  clang/test/CodeGenCXX/constructor-destructor-return-this.cpp
  clang/test/CodeGenCXX/constructor-init.cpp
  clang/test/CodeGenCXX/delete.cpp
  clang/test/CodeGenCXX/devirtualize-virtual-function-calls-final.cpp
  clang/test/CodeGenCXX/interleaving-member-function-pointers.cpp
  clang/test/CodeGenCXX/interleaving-virtual-base.cpp
  clang/test/CodeGenCXX/interleaving-virtual-calls.cpp
  clang/test/CodeGenCXX/type-metadata.cpp
  clang/test/CodeGenCXX/ubsan-vtable-checks.cpp
  clang/test/CodeGenCXX/virtual-base-cast.cpp
  compiler-rt/test/cfi/CMakeLists.txt
  compiler-rt/test/cfi/anon-namespace.cpp
  compiler-rt/test/cfi/create-derivers.test
  compiler-rt/test/cfi/cross-dso/icall/lit.local.cfg.py
  compiler-rt/test/cfi/cross-dso/lit.local.cfg.py
  compiler-rt/test/cfi/lit.cfg.py
  compiler-rt/test/cfi/lit.site.cfg.py.in
  compiler-rt/test/cfi/mfcall.cpp
  compiler-rt/test/cfi/multiple-inheritance.cpp
  compiler-rt/test/cfi/simple-fail.cpp
  compiler-rt/test/cfi/vdtor.cpp
  compiler-rt/test/lit.common.configured.in

Index: compiler-rt/test/lit.common.configured.in
===
--- compiler-rt/test/lit.common.configured.in
+++ compiler-rt/test/lit.common.configured.in
@@ -36,6 +36,7 @@
 set_default("use_thinlto", False)
 set_default("use_lto", config.use_thinlto)
 set_default("use_newpm", False)
+set_default("use_interleaving", False)
 set_default("android", @ANDROID_PYBOOL@)
 set_default("android_ndk_version", @ANDROID_NDK_VERSION@)
 set_default("android_serial", "@ANDROID_SERIAL_FOR_TESTING@")
Index: compiler-rt/test/cfi/vdtor.cpp
===
--- compiler-rt/test/cfi/vdtor.cpp
+++ compiler-rt/test/cfi/vdtor.cpp
@@ -14,7 +14,7 @@
 // RUN: %run %t5 2>&1 | FileCheck --check-prefix=NCFI %s
 
 // RUN: %clangxx_cfi_diag -o %t6 %s
-// RUN: %run %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %interleave_diag %run %t6 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
 
 // Tests that the CFI enforcement also applies to virtual destructor calls made
 // via 'delete'.
Index: compiler-rt/test/cfi/simple-fail.cpp
===
--- compiler-rt/test/cfi/simple-fail.cpp
+++ compiler-rt/test/cfi/simple-fail.cpp
@@ -47,12 +47,12 @@
 // RUN: %expect_crash %run %t16 2>&1 | FileCheck --check-prefix=CFI %s
 
 // RUN: %clangxx_cfi_diag -o %t17 %s
-// RUN: %run %t17 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
+// RUN: %interleave_diag %run %t17 2>&1 | FileCheck --check-prefix=CFI-DIAG %s
 
 // RUN: %clangxx -o %t18 %s
 // RUN: %run %t18 2>&1 | FileCheck --check-prefix=NCFI %s
 
-// RUN: %clangxx_cfi -DCHECK_NO_SANITIZE_CFI -o %t19 %s
+// RUN: %clangxx_cfi_no_interleaving -DCHECK_NO_SANITIZE_CFI -o %t19 %s
 // RUN: %run %t19 2>&1 | FileCheck --check-prefix=NCFI %s
 
 // Tests that the CFI mechanism crashes the program when making a virtual call
@@ -95,6 +95,7 @@
   // CFI-DIAG-NEXT: note: vtable is of type '{{(struct )?}}A'
   ((B *)a)->f(); // UB here
 
+  // INTERLEAVING-NCFI-NOT: {{^2$}}
   // CFI-NOT: {{^2$}}
   // NCFI: {{^2$}}
   fprintf(stderr, "2\n");
Index: compiler-rt/test/cfi/multiple-inheritance.cpp
===
--- compiler-rt/test/cfi/multiple-inheritance.cpp
+++ compiler-rt/test/cfi/multiple-inheritance.

[PATCH] D67865: [clang-tidy] Finds uses of OSRead* calls on macOS that may mask unexpected behavior due to unaligned reads

2019-09-20 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: clang-tidy/objc/AvoidOSReadCheck.cpp:21
+void AvoidOSReadCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  callExpr(callee((functionDecl(hasAnyName(

Please add check if language is Objective-C.



Comment at: docs/ReleaseNotes.rst:103
+
+  Finds uses of OSRead* calls on macOS that may mask unexpected behavior due to
+  unaligned reads.

Please enclose OSRead* in double back-ticks.



Comment at: docs/clang-tidy/checks/objc-avoid-osread.rst:6
+
+Finds usages of ``OSRead{Big|Little}Int{16|32|64}`` and associated functions 
which
+should be avoided due to potential unaligned read problems.

Please synchronize with sentence in Release Notes.



Comment at: docs/clang-tidy/checks/objc-avoid-osread.rst:29
+.. code:: c
+   OS_INLINE uint64_t _OSReadInt64(const volatile void *base, uintptr_t 
byteOffset)
+   {

Please separate with empty line.


Repository:
  rCTE Clang Tools Extra

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

https://reviews.llvm.org/D67865



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D67865: [clang-tidy] Finds uses of OSRead* calls on macOS that may mask unexpected behavior due to unaligned reads

2019-09-20 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: clang-tidy/objc/AvoidOSReadCheck.h:5
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.

License was changed this year. Same in source file.


Repository:
  rCTE Clang Tools Extra

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

https://reviews.llvm.org/D67865



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372444 - [clang-scan-deps] strip the --serialize-diagnostics argument

2019-09-20 Thread Alex Lorenz via cfe-commits
Author: arphaman
Date: Fri Sep 20 17:17:26 2019
New Revision: 372444

URL: http://llvm.org/viewvc/llvm-project?rev=372444&view=rev
Log:
[clang-scan-deps] strip the --serialize-diagnostics argument

This ensures that clang-scan-deps won't write out diagnostics when
scanning dependencies.

Added:
cfe/trunk/test/ClangScanDeps/Inputs/strip_diag_serialize.json
cfe/trunk/test/ClangScanDeps/strip_diag_serialize.cpp
Modified:
cfe/trunk/include/clang/Tooling/ArgumentsAdjusters.h
cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp
cfe/trunk/tools/clang-scan-deps/ClangScanDeps.cpp

Modified: cfe/trunk/include/clang/Tooling/ArgumentsAdjusters.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/ArgumentsAdjusters.h?rev=372444&r1=372443&r2=372444&view=diff
==
--- cfe/trunk/include/clang/Tooling/ArgumentsAdjusters.h (original)
+++ cfe/trunk/include/clang/Tooling/ArgumentsAdjusters.h Fri Sep 20 17:17:26 
2019
@@ -43,6 +43,10 @@ ArgumentsAdjuster getClangSyntaxOnlyAdju
 /// arguments.
 ArgumentsAdjuster getClangStripOutputAdjuster();
 
+/// Gets an argument adjuster which removes command line arguments related to
+/// diagnostic serialization.
+ArgumentsAdjuster getClangStripSerializeDiagnosticAdjuster();
+
 /// Gets an argument adjuster which removes dependency-file
 /// related command line arguments.
 ArgumentsAdjuster getClangStripDependencyFileAdjuster();

Modified: cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp?rev=372444&r1=372443&r2=372444&view=diff
==
--- cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp (original)
+++ cfe/trunk/lib/Tooling/ArgumentsAdjusters.cpp Fri Sep 20 17:17:26 2019
@@ -57,6 +57,22 @@ ArgumentsAdjuster getClangStripOutputAdj
   };
 }
 
+ArgumentsAdjuster getClangStripSerializeDiagnosticAdjuster() {
+  return [](const CommandLineArguments &Args, StringRef /*unused*/) {
+CommandLineArguments AdjustedArgs;
+for (size_t i = 0, e = Args.size(); i < e; ++i) {
+  StringRef Arg = Args[i];
+  if (Arg == "--serialize-diagnostics") {
+// Skip the diagnostic output argument.
+++i;
+continue;
+  }
+  AdjustedArgs.push_back(Args[i]);
+}
+return AdjustedArgs;
+  };
+}
+
 ArgumentsAdjuster getClangStripDependencyFileAdjuster() {
   return [](const CommandLineArguments &Args, StringRef /*unused*/) {
 CommandLineArguments AdjustedArgs;

Added: cfe/trunk/test/ClangScanDeps/Inputs/strip_diag_serialize.json
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ClangScanDeps/Inputs/strip_diag_serialize.json?rev=372444&view=auto
==
--- cfe/trunk/test/ClangScanDeps/Inputs/strip_diag_serialize.json (added)
+++ cfe/trunk/test/ClangScanDeps/Inputs/strip_diag_serialize.json Fri Sep 20 
17:17:26 2019
@@ -0,0 +1,7 @@
+[
+{
+  "directory": "DIR",
+  "command": "clang -E -fsyntax-only DIR/strip_diag_serialize_input.cpp 
--serialize-diagnostics /does/not/exist",
+  "file": "DIR/strip_diag_serialize_input.cpp"
+}
+]

Added: cfe/trunk/test/ClangScanDeps/strip_diag_serialize.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ClangScanDeps/strip_diag_serialize.cpp?rev=372444&view=auto
==
--- cfe/trunk/test/ClangScanDeps/strip_diag_serialize.cpp (added)
+++ cfe/trunk/test/ClangScanDeps/strip_diag_serialize.cpp Fri Sep 20 17:17:26 
2019
@@ -0,0 +1,11 @@
+// RUN: rm -rf %t.dir
+// RUN: rm -rf %t.cdb
+// RUN: mkdir -p %t.dir
+// RUN: cp %s %t.dir/strip_diag_serialize_input.cpp
+// RUN: sed -e "s|DIR|%/t.dir|g" %S/Inputs/strip_diag_serialize.json > %t.cdb
+//
+// RUN: clang-scan-deps -compilation-database %t.cdb 2>&1 | FileCheck %s
+// CHECK-NOT: unable to open file
+// CHECK: strip_diag_serialize_input.cpp
+
+#warning "diagnostic"

Modified: cfe/trunk/tools/clang-scan-deps/ClangScanDeps.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/clang-scan-deps/ClangScanDeps.cpp?rev=372444&r1=372443&r2=372444&view=diff
==
--- cfe/trunk/tools/clang-scan-deps/ClangScanDeps.cpp (original)
+++ cfe/trunk/tools/clang-scan-deps/ClangScanDeps.cpp Fri Sep 20 17:17:26 2019
@@ -266,6 +266,8 @@ int main(int argc, const char **argv) {
 AdjustedArgs.push_back("-Wno-error");
 return AdjustedArgs;
   });
+  AdjustingCompilations->appendArgumentsAdjuster(
+  tooling::getClangStripSerializeDiagnosticAdjuster());
 
   SharedStream Errs(llvm::errs());
   // Print out the dependency results to STDOUT by default.


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commi

[PATCH] D65917: [clang-tidy] Added check for the Google style guide's category method naming rule.

2019-09-20 Thread Stephane Moore via Phabricator via cfe-commits
stephanemoore requested changes to this revision.
stephanemoore added inline comments.
This revision now requires changes to proceed.



Comment at: 
clang-tools-extra/clang-tidy/google/RequireCategoryMethodPrefixesCheck.cpp:23
+  Finder->addMatcher(objcMethodDecl(hasDeclContext(
+  objcCategoryDecl())).bind(CustomCategoryMethodIdentifier), this);
+}

dgatwood wrote:
> stephanemoore wrote:
> > Technically category method prefixing is only strictly enforced on classes 
> > that are shared:
> > "If a class is not shared with other projects, categories extending it may 
> > omit name prefixes and method name prefixes."
> > https://github.com/google/styleguide/blob/gh-pages/objcguide.md#category-naming
> > 
> > With that in mind, perhaps we should match on categories on classes that 
> > extend classes that are declared in system headers? I think you can 
> > accomplish that by adding a custom inner matcher in `objcCategoryDecl` 
> > which pulls out the Objective-C interface using 
> > [clang::ObjCCategoryDecl::getClassInterface](https://clang.llvm.org/doxygen/classclang_1_1ObjCCategoryDecl.html#acdb14eeca277cfa745a4e8e842312008)
> >  and then add `isExpansionInSystemHeader` as an inner matcher on the custom 
> > inner matcher. WDYT? Let me know if you need help putting together.
> Requiring users to specify which classes should be covered by this checker 
> doesn't scale well.  System classes are a tiny fraction of the shared code 
> that we bring in.  Proto classes alone probably outnumber system framework 
> classes 10:1, plus all the shared code from other internal framework teams.  
> A list of every shared class that we bring in would be massive, and 
> generating it programmatically would be relatively expensive.  The same 
> problem exists for a list of prefixes to protect.
> 
> Also with that approach, a mistake by a person or script that maintains such 
> a list would result in **not** getting warnings.  Silent failures are the 
> worst kind of failure, because you don't even know that something is going 
> wrong.  By contrast, if you require the user to specify a list of prefixes to 
> ignore, as this patch does, then any mistake by someone maintaining the lest 
> results in getting **extra** warnings, which makes it obvious that something 
> is wrong and needs to be fixed.
> 
> I realize that ostensibly a team could own some code that is also shared, and 
> it could have the same prefix as their app.  But there's no real reason to 
> care about that case.  After all, if someone changes the shared code and it 
> breaks the category, it's the same team, so their tests should catch the 
> breakage, unlike changes made by some far-flung team on the other side of the 
> world.  Also, if they break their own code, they also have permission to fix 
> that breakage without additional approvals.  So that edge case is largely 
> academic; if anybody asks for a way to not ignore specific classes that have 
> an exempt prefix, we can certainly add that feature later pretty easily, but 
> I really doubt anybody would bother to use it.  :-)
> Requiring users to specify which classes should be covered by this checker 
> doesn't scale well.

I am not convinced that listing exemptions scales well either. In 
[D51832](https://reviews.llvm.org/D51832), we abandoned a growing list of 
exemptions that were being used to enforce naming conventions. I am worried 
that a list of exempt prefixes will also end up growing in a similar fashion.

> System classes are a tiny fraction of the shared code that we bring in.

That is true.

However, system classes generally have the most breadth and are the most 
sensitive (for example, there was a recent bug introduced when someone declared 
a category on `UIImageView` with an unprefixed getter named `animationDuration` 
which overrode the actual 
[`animationDuration`](https://developer.apple.com/documentation/uikit/uiimageview/1621058-animationduration?language=objc)
 property on `UIImageView`).

> Proto classes alone probably outnumber system framework classes 10:1, plus 
> all the shared code from other internal framework teams.

That is true but proto classes and internal shared code also tend to have much 
more limited scope.

My concern with the check in its current form is that it has a strong potential 
to be noisy by default. That is, if you enable this check without specifying 
any exempt prefixes then it will warn for _any category_, including categories 
on classes that are not shared which do not require a prefix. Moreover, the 
check provides no option to exempt classes that do not have prefixes at all 
(prefixes are only required for classes that are shared per [Google Objective-C 
class naming 
guidelines](https://github.com/google/styleguide/blob/gh-pages/objcguide.md#class-names)).

Generated Objective-C Protocol Buffer classes should be pretty easy to target 
since they have a common base class of `GPBMessage`. It should be pre

[PATCH] D67737: [clang-tidy] Add check for classes missing -hash ⚠️

2019-09-20 Thread Stephane Moore via Phabricator via cfe-commits
stephanemoore marked 2 inline comments as done.
stephanemoore added a comment.

Thanks for the review!




Comment at: clang-tools-extra/clang-tidy/objc/MissingHashCheck.cpp:56
+  const auto *ID = Result.Nodes.getNodeAs("impl");
+  diag(ID->getLocation(), "%0 implements -isEqual: without implementing -hash")
+  << ID;

aaron.ballman wrote:
> stephanemoore wrote:
> > aaron.ballman wrote:
> > > Do you think we could generate a fixit to add the `hash` method? Do you 
> > > think we could even add a default implementation that returns the pointer 
> > > to the object (assuming that's the correct default behavior)?
> > > Do you think we could generate a fixit to add the hash method?
> > 
> > I think it would be pretty tough to generate a reasonable hash method 
> > without knowing the equality and hashing semantics that the scenario calls 
> > for.
> > 
> > Here is an analogous situation presented in C++ (please excuse the hastily 
> > assembled sample code):
> > ```
> > namespace {
> > 
> > class NSObject {
> >   public:
> > NSObject() {}
> > virtual ~NSObject() {}
> > 
> > virtual bool isEqual(const NSObject *other) const {
> >   return this == other;
> > }
> > virtual unsigned long long hash() const {
> >   return (unsigned long long)this;
> > }
> > };
> > 
> > }
> > 
> > #include 
> > #include 
> > 
> > namespace {
> > 
> > class Movie : public virtual NSObject {
> >   private:
> > std::string name;
> > std::string language;
> > 
> >   public:
> > Movie(std::string name, std::string language) : name(name), 
> > language(language) {}
> > ~Movie() override {}
> > bool isEqual(const NSObject *other) const override {
> >   if (auto otherMovie = dynamic_cast(other)) {
> > // Movies with the same name are considered equal
> > // regardless of the language of the screening.
> > return name == otherMovie->name;
> >   }
> >   return false;
> > }
> > unsigned long long hash() const override {
> >   return name.length();
> > }
> > };
> > 
> > }
> > ```
> > 
> > As before, the base class uses pointer equality and the pointer as a hash. 
> > A subclass may arbitrarily add additional state but only the developer 
> > knows which added state factors into equality operations and consequently 
> > should be considered—but not necessarily required—in the hash operation. 
> > The matter can technically get even more complicated if an object stores 
> > state externally. I would hope that externally stored state would not 
> > factor into the equality operation of an object but I hesitate to make an 
> > assumption.
> > 
> > The developer is also in the best position to prioritize different 
> > properties of the hash function including performance, collision 
> > resistance, uniformity, and non-invertibility.
> > 
> > Writing effective hash functions is probably difficult independent of the 
> > programming language but it might help to consider some specific examples 
> > in Objective-C. 
> > [GPBMessage](https://github.com/protocolbuffers/protobuf/blob/ffa6bfc/objectivec/GPBMessage.m),
> >  the Objective-C base class for Google Protocol Buffer message classes, 
> > implements `-hash` but has an [extensive 
> > comment](https://github.com/protocolbuffers/protobuf/blob/ffa6bfc/objectivec/GPBMessage.m#L2749)
> >  explaining that its complex but generic implementation is not generally 
> > optimal and recommends that developers override `-hash` and `-isEqual:` to 
> > optimize for runtime performance. In contrast, the basic collection classes 
> > in Apple's Foundation framework have [surprisingly simple hash 
> > behavior](https://github.com/stephanemoore/archives/blob/master/objc/tips/hashing-basic-collections.md)
> >  that clearly indicate priority to runtime performance over uniformity and 
> > collision resistance. The former is a conservatively expensive hash 
> > function and the latter is a conservatively inexpensive hash function.
> > 
> > > Do you think we could even add a default implementation that returns the 
> > > pointer to the object (assuming that's the correct default behavior)?
> > 
> > A hash returning the object pointer is already inherited from the 
> > superclass (i..e, `-[NSObject hash]`). Defining an override that returns 
> > the object pointer would be a functional no-op for classes directly derived 
> > from `NSObject` (although the explicit override could be useful as a signal 
> > of intended behavior).
> > A hash returning the object pointer is already inherited from the 
> > superclass (i..e, -[NSObject hash]). Defining an override that returns the 
> > object pointer would be a functional no-op for classes directly derived 
> > from NSObject (although the explicit override could be useful as a signal 
> > of intended behavior).
> 
> Ah, my ObjC knowledge is weak and I was thinking that the one inherited from 
> `NSObject` would be hidden. Thank you for the 

[PATCH] D67737: [clang-tidy] Add check for classes missing -hash ⚠️

2019-09-20 Thread Stephane Moore via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
stephanemoore marked an inline comment as done.
Closed by commit rL372445: [clang-tidy] Add check for classes missing -hash ⚠️ 
(authored by stephanemoore, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D67737?vs=220823&id=221147#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D67737

Files:
  clang-tools-extra/trunk/clang-tidy/objc/CMakeLists.txt
  clang-tools-extra/trunk/clang-tidy/objc/MissingHashCheck.cpp
  clang-tools-extra/trunk/clang-tidy/objc/MissingHashCheck.h
  clang-tools-extra/trunk/clang-tidy/objc/ObjCTidyModule.cpp
  clang-tools-extra/trunk/docs/ReleaseNotes.rst
  clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
  clang-tools-extra/trunk/docs/clang-tidy/checks/objc-missing-hash.rst
  clang-tools-extra/trunk/test/clang-tidy/objc-missing-hash.m

Index: clang-tools-extra/trunk/clang-tidy/objc/ObjCTidyModule.cpp
===
--- clang-tools-extra/trunk/clang-tidy/objc/ObjCTidyModule.cpp
+++ clang-tools-extra/trunk/clang-tidy/objc/ObjCTidyModule.cpp
@@ -12,6 +12,7 @@
 #include "AvoidNSErrorInitCheck.h"
 #include "AvoidSpinlockCheck.h"
 #include "ForbiddenSubclassingCheck.h"
+#include "MissingHashCheck.h"
 #include "PropertyDeclarationCheck.h"
 #include "SuperSelfCheck.h"
 
@@ -30,6 +31,8 @@
 "objc-avoid-spinlock");
 CheckFactories.registerCheck(
 "objc-forbidden-subclassing");
+CheckFactories.registerCheck(
+"objc-missing-hash");
 CheckFactories.registerCheck(
 "objc-property-declaration");
 CheckFactories.registerCheck(
Index: clang-tools-extra/trunk/clang-tidy/objc/CMakeLists.txt
===
--- clang-tools-extra/trunk/clang-tidy/objc/CMakeLists.txt
+++ clang-tools-extra/trunk/clang-tidy/objc/CMakeLists.txt
@@ -4,6 +4,7 @@
   AvoidNSErrorInitCheck.cpp
   AvoidSpinlockCheck.cpp
   ForbiddenSubclassingCheck.cpp
+  MissingHashCheck.cpp
   ObjCTidyModule.cpp
   PropertyDeclarationCheck.cpp
   SuperSelfCheck.cpp
Index: clang-tools-extra/trunk/clang-tidy/objc/MissingHashCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/objc/MissingHashCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/objc/MissingHashCheck.cpp
@@ -0,0 +1,62 @@
+//===--- MissingHashCheck.cpp - clang-tidy ===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "MissingHashCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace objc {
+
+namespace {
+
+AST_MATCHER_P(ObjCImplementationDecl, hasInterface,
+  ast_matchers::internal::Matcher, Base) {
+  const ObjCInterfaceDecl *InterfaceDecl = Node.getClassInterface();
+  return Base.matches(*InterfaceDecl, Finder, Builder);
+}
+
+AST_MATCHER_P(ObjCContainerDecl, hasInstanceMethod,
+  ast_matchers::internal::Matcher, Base) {
+  // Check each instance method against the provided matcher.
+  for (const auto *I : Node.instance_methods()) {
+if (Base.matches(*I, Finder, Builder))
+  return true;
+  }
+  return false;
+}
+
+} // namespace
+
+void MissingHashCheck::registerMatchers(MatchFinder *Finder) {
+  // This check should only be applied to Objective-C sources.
+  if (!getLangOpts().ObjC)
+return;
+
+  Finder->addMatcher(
+  objcMethodDecl(
+  hasName("isEqual:"), isInstanceMethod(),
+  hasDeclContext(objcImplementationDecl(
+ hasInterface(isDirectlyDerivedFrom("NSObject")),
+ unless(hasInstanceMethod(hasName("hash"
+ .bind("impl"))),
+  this);
+}
+
+void MissingHashCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *ID = Result.Nodes.getNodeAs("impl");
+  diag(ID->getLocation(), "%0 implements -isEqual: without implementing -hash")
+  << ID;
+}
+
+} // namespace objc
+} // namespace tidy
+} // namespace clang
Index: clang-tools-extra/trunk/clang-tidy/objc/MissingHashCheck.h
===
--- clang-tools-extra/trunk/clang-tidy/objc/MissingHashCheck.h
+++ clang-tools-extra/trunk/clang-tidy/objc/MissingHashCheck.h
@@ -0,0 +1,35 @@
+//===--- MissingHashCheck.h - clang-tidy *- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https

r372448 - Improve -Wtautological-overlap-compare

2019-09-20 Thread Richard Trieu via cfe-commits
Author: rtrieu
Date: Fri Sep 20 19:37:10 2019
New Revision: 372448

URL: http://llvm.org/viewvc/llvm-project?rev=372448&view=rev
Log:
Improve -Wtautological-overlap-compare

Allow this warning to detect a larger number of constant values, including
negative numbers, and handle non-int types better.

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

Modified:
cfe/trunk/docs/ReleaseNotes.rst
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/lib/Analysis/ReachableCode.cpp
cfe/trunk/test/Analysis/cfg.cpp
cfe/trunk/test/Sema/warn-overlap.c
cfe/trunk/test/Sema/warn-unreachable.c
cfe/trunk/test/SemaCXX/warn-unreachable.cpp

Modified: cfe/trunk/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=372448&r1=372447&r2=372448&view=diff
==
--- cfe/trunk/docs/ReleaseNotes.rst (original)
+++ cfe/trunk/docs/ReleaseNotes.rst Fri Sep 20 19:37:10 2019
@@ -51,7 +51,8 @@ Major New Features
 Improvements to Clang's diagnostics
 ^^^
 
-- ...
+- -Wtautological-overlap-compare will warn on negative numbers and non-int
+  types.
 
 Non-comprehensive list of changes in this release
 -

Modified: cfe/trunk/lib/Analysis/CFG.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CFG.cpp?rev=372448&r1=372447&r2=372448&view=diff
==
--- cfe/trunk/lib/Analysis/CFG.cpp (original)
+++ cfe/trunk/lib/Analysis/CFG.cpp Fri Sep 20 19:37:10 2019
@@ -70,11 +70,35 @@ static SourceLocation GetEndLoc(Decl *D)
   return D->getLocation();
 }
 
+/// Returns true on constant values based around a single IntegerLiteral.
+/// Allow for use of parentheses, integer casts, and negative signs.
+static bool IsIntegerLiteralConstantExpr(const Expr *E) {
+  // Allow parentheses
+  E = E->IgnoreParens();
+
+  // Allow conversions to different integer kind.
+  if (const auto *CE = dyn_cast(E)) {
+if (CE->getCastKind() != CK_IntegralCast)
+  return false;
+E = CE->getSubExpr();
+  }
+
+  // Allow negative numbers.
+  if (const auto *UO = dyn_cast(E)) {
+if (UO->getOpcode() != UO_Minus)
+  return false;
+E = UO->getSubExpr();
+  }
+
+  return isa(E);
+}
+
 /// Helper for tryNormalizeBinaryOperator. Attempts to extract an 
IntegerLiteral
-/// or EnumConstantDecl from the given Expr. If it fails, returns nullptr.
+/// constant expression or EnumConstantDecl from the given Expr. If it fails,
+/// returns nullptr.
 static const Expr *tryTransformToIntOrEnumConstant(const Expr *E) {
   E = E->IgnoreParens();
-  if (isa(E))
+  if (IsIntegerLiteralConstantExpr(E))
 return E;
   if (auto *DR = dyn_cast(E->IgnoreParenImpCasts()))
 return isa(DR->getDecl()) ? DR : nullptr;
@@ -121,11 +145,11 @@ tryNormalizeBinaryOperator(const BinaryO
 static bool areExprTypesCompatible(const Expr *E1, const Expr *E2) {
   // User intent isn't clear if they're mixing int literals with enum
   // constants.
-  if (isa(E1) != isa(E2))
+  if (isa(E1) != isa(E2))
 return false;
 
   // Integer literal comparisons, regardless of literal type, are acceptable.
-  if (isa(E1))
+  if (!isa(E1))
 return true;
 
   // IntegerLiterals are handled above and only EnumConstantDecls are expected
@@ -1081,6 +1105,10 @@ private:
 // * Variable x is equal to the largest literal.
 // * Variable x is greater than largest literal.
 bool AlwaysTrue = true, AlwaysFalse = true;
+// Track value of both subexpressions.  If either side is always
+// true/false, another warning should have already been emitted.
+bool LHSAlwaysTrue = true, LHSAlwaysFalse = true;
+bool RHSAlwaysTrue = true, RHSAlwaysFalse = true;
 for (const llvm::APSInt &Value : Values) {
   TryResult Res1, Res2;
   Res1 = analyzeLogicOperatorCondition(BO1, Value, L1);
@@ -1096,10 +1124,16 @@ private:
 AlwaysTrue &= (Res1.isTrue() || Res2.isTrue());
 AlwaysFalse &= !(Res1.isTrue() || Res2.isTrue());
   }
+
+  LHSAlwaysTrue &= Res1.isTrue();
+  LHSAlwaysFalse &= Res1.isFalse();
+  RHSAlwaysTrue &= Res2.isTrue();
+  RHSAlwaysFalse &= Res2.isFalse();
 }
 
 if (AlwaysTrue || AlwaysFalse) {
-  if (BuildOpts.Observer)
+  if (!LHSAlwaysTrue && !LHSAlwaysFalse && !RHSAlwaysTrue &&
+  !RHSAlwaysFalse && BuildOpts.Observer)
 BuildOpts.Observer->compareAlwaysTrue(B, AlwaysTrue);
   return TryResult(AlwaysTrue);
 }

Modified: cfe/trunk/lib/Analysis/ReachableCode.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ReachableCode.cpp?rev=372448&r1=372447&r2=372448&view=diff
==
--- cfe/trunk/lib/Analysis/ReachableCode.cpp (original)
+++ cfe/trunk/lib/Analysis/ReachableCode.cpp Fri Sep 20 19:37:10 2019
@@ -247,7 +247

[PATCH] D66044: Extend -Wtautological-overlap-compare to accept negative values and integer conversions

2019-09-20 Thread Richard Trieu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL372448: Improve -Wtautological-overlap-compare (authored by 
rtrieu, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D66044?vs=215021&id=221151#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D66044

Files:
  cfe/trunk/docs/ReleaseNotes.rst
  cfe/trunk/lib/Analysis/CFG.cpp
  cfe/trunk/lib/Analysis/ReachableCode.cpp
  cfe/trunk/test/Analysis/cfg.cpp
  cfe/trunk/test/Sema/warn-overlap.c
  cfe/trunk/test/Sema/warn-unreachable.c
  cfe/trunk/test/SemaCXX/warn-unreachable.cpp

Index: cfe/trunk/lib/Analysis/ReachableCode.cpp
===
--- cfe/trunk/lib/Analysis/ReachableCode.cpp
+++ cfe/trunk/lib/Analysis/ReachableCode.cpp
@@ -247,7 +247,7 @@
 }
 case Stmt::UnaryOperatorClass: {
   const UnaryOperator *UO = cast(S);
-  if (UO->getOpcode() != UO_LNot)
+  if (UO->getOpcode() != UO_LNot && UO->getOpcode() != UO_Minus)
 return false;
   bool SilenceableCondValNotSet =
   SilenceableCondVal && SilenceableCondVal->getBegin().isInvalid();
Index: cfe/trunk/lib/Analysis/CFG.cpp
===
--- cfe/trunk/lib/Analysis/CFG.cpp
+++ cfe/trunk/lib/Analysis/CFG.cpp
@@ -70,11 +70,35 @@
   return D->getLocation();
 }
 
+/// Returns true on constant values based around a single IntegerLiteral.
+/// Allow for use of parentheses, integer casts, and negative signs.
+static bool IsIntegerLiteralConstantExpr(const Expr *E) {
+  // Allow parentheses
+  E = E->IgnoreParens();
+
+  // Allow conversions to different integer kind.
+  if (const auto *CE = dyn_cast(E)) {
+if (CE->getCastKind() != CK_IntegralCast)
+  return false;
+E = CE->getSubExpr();
+  }
+
+  // Allow negative numbers.
+  if (const auto *UO = dyn_cast(E)) {
+if (UO->getOpcode() != UO_Minus)
+  return false;
+E = UO->getSubExpr();
+  }
+
+  return isa(E);
+}
+
 /// Helper for tryNormalizeBinaryOperator. Attempts to extract an IntegerLiteral
-/// or EnumConstantDecl from the given Expr. If it fails, returns nullptr.
+/// constant expression or EnumConstantDecl from the given Expr. If it fails,
+/// returns nullptr.
 static const Expr *tryTransformToIntOrEnumConstant(const Expr *E) {
   E = E->IgnoreParens();
-  if (isa(E))
+  if (IsIntegerLiteralConstantExpr(E))
 return E;
   if (auto *DR = dyn_cast(E->IgnoreParenImpCasts()))
 return isa(DR->getDecl()) ? DR : nullptr;
@@ -121,11 +145,11 @@
 static bool areExprTypesCompatible(const Expr *E1, const Expr *E2) {
   // User intent isn't clear if they're mixing int literals with enum
   // constants.
-  if (isa(E1) != isa(E2))
+  if (isa(E1) != isa(E2))
 return false;
 
   // Integer literal comparisons, regardless of literal type, are acceptable.
-  if (isa(E1))
+  if (!isa(E1))
 return true;
 
   // IntegerLiterals are handled above and only EnumConstantDecls are expected
@@ -1081,6 +1105,10 @@
 // * Variable x is equal to the largest literal.
 // * Variable x is greater than largest literal.
 bool AlwaysTrue = true, AlwaysFalse = true;
+// Track value of both subexpressions.  If either side is always
+// true/false, another warning should have already been emitted.
+bool LHSAlwaysTrue = true, LHSAlwaysFalse = true;
+bool RHSAlwaysTrue = true, RHSAlwaysFalse = true;
 for (const llvm::APSInt &Value : Values) {
   TryResult Res1, Res2;
   Res1 = analyzeLogicOperatorCondition(BO1, Value, L1);
@@ -1096,10 +1124,16 @@
 AlwaysTrue &= (Res1.isTrue() || Res2.isTrue());
 AlwaysFalse &= !(Res1.isTrue() || Res2.isTrue());
   }
+
+  LHSAlwaysTrue &= Res1.isTrue();
+  LHSAlwaysFalse &= Res1.isFalse();
+  RHSAlwaysTrue &= Res2.isTrue();
+  RHSAlwaysFalse &= Res2.isFalse();
 }
 
 if (AlwaysTrue || AlwaysFalse) {
-  if (BuildOpts.Observer)
+  if (!LHSAlwaysTrue && !LHSAlwaysFalse && !RHSAlwaysTrue &&
+  !RHSAlwaysFalse && BuildOpts.Observer)
 BuildOpts.Observer->compareAlwaysTrue(B, AlwaysTrue);
   return TryResult(AlwaysTrue);
 }
Index: cfe/trunk/docs/ReleaseNotes.rst
===
--- cfe/trunk/docs/ReleaseNotes.rst
+++ cfe/trunk/docs/ReleaseNotes.rst
@@ -51,7 +51,8 @@
 Improvements to Clang's diagnostics
 ^^^
 
-- ...
+- -Wtautological-overlap-compare will warn on negative numbers and non-int
+  types.
 
 Non-comprehensive list of changes in this release
 -
Index: cfe/trunk/test/SemaCXX/warn-unreachable.cpp
===
--- cfe/trunk/test/SemaCXX/warn-unreachable.cpp
+++ cfe/trunk/test/SemaCXX/warn-unr

r372452 - Revert assertion added by r372394

2019-09-20 Thread Yaxun Liu via cfe-commits
Author: yaxunl
Date: Fri Sep 20 19:51:44 2019
New Revision: 372452

URL: http://llvm.org/viewvc/llvm-project?rev=372452&view=rev
Log:
Revert assertion added by r372394

The assertion added by r372394 causes CUDA test in test-suite to assert.

The assertion was not there originally, so revert it.


Modified:
cfe/trunk/lib/Sema/SemaCUDA.cpp

Modified: cfe/trunk/lib/Sema/SemaCUDA.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCUDA.cpp?rev=372452&r1=372451&r2=372452&view=diff
==
--- cfe/trunk/lib/Sema/SemaCUDA.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCUDA.cpp Fri Sep 20 19:51:44 2019
@@ -396,7 +396,6 @@ bool Sema::inferCUDATargetForImplicitSpe
 
   // We either setting attributes first time, or the inferred ones must match
   // previously set ones.
-  assert(!(HasD || HasH) || (NeedsD == HasD && NeedsH == HasH));
   if (NeedsD && !HasD)
 MemberDecl->addAttr(CUDADeviceAttr::CreateImplicit(Context));
   if (NeedsH && !HasH)


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r372453 - Merge and improve code that detects same value in comparisons.

2019-09-20 Thread Richard Trieu via cfe-commits
Author: rtrieu
Date: Fri Sep 20 20:02:26 2019
New Revision: 372453

URL: http://llvm.org/viewvc/llvm-project?rev=372453&view=rev
Log:
Merge and improve code that detects same value in comparisons.

-Wtautological-overlap-compare and self-comparison from -Wtautological-compare
relay on detecting the same operand in different locations.  Previously, each
warning had it's own operand checker.  Now, both are merged together into
one function that each can call.  The function also now looks through member
access and array accesses.

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

Modified:
cfe/trunk/docs/ReleaseNotes.rst
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/Analysis/array-struct-region.cpp
cfe/trunk/test/Sema/warn-overlap.c
cfe/trunk/test/SemaCXX/compare-cxx2a.cpp
cfe/trunk/test/SemaCXX/self-comparison.cpp

Modified: cfe/trunk/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/ReleaseNotes.rst?rev=372453&r1=372452&r2=372453&view=diff
==
--- cfe/trunk/docs/ReleaseNotes.rst (original)
+++ cfe/trunk/docs/ReleaseNotes.rst Fri Sep 20 20:02:26 2019
@@ -53,6 +53,9 @@ Improvements to Clang's diagnostics
 
 - -Wtautological-overlap-compare will warn on negative numbers and non-int
   types.
+- -Wtautological-compare for self comparisons and
+  -Wtautological-overlap-compare will now look through member and array
+  access to determine if two operand expressions are the same.
 
 Non-comprehensive list of changes in this release
 -

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=372453&r1=372452&r2=372453&view=diff
==
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Sep 20 20:02:26 2019
@@ -906,6 +906,11 @@ public:
 return skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
   }
 
+  /// Checks that the two Expr's will refer to the same value as a comparison
+  /// operand.  The caller must ensure that the values referenced by the Expr's
+  /// are not modified between E1 and E2 or the result my be invalid.
+  static bool isSameComparisonOperand(const Expr* E1, const Expr* E2);
+
   static bool classof(const Stmt *T) {
 return T->getStmtClass() >= firstExprConstant &&
T->getStmtClass() <= lastExprConstant;

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=372453&r1=372452&r2=372453&view=diff
==
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Fri Sep 20 20:02:26 2019
@@ -3921,6 +3921,111 @@ bool Expr::refersToGlobalRegisterVar() c
   return false;
 }
 
+bool Expr::isSameComparisonOperand(const Expr* E1, const Expr* E2) {
+  E1 = E1->IgnoreParens();
+  E2 = E2->IgnoreParens();
+
+  if (E1->getStmtClass() != E2->getStmtClass())
+return false;
+
+  switch (E1->getStmtClass()) {
+default:
+  return false;
+case CXXThisExprClass:
+  return true;
+case DeclRefExprClass: {
+  // DeclRefExpr without an ImplicitCastExpr can happen for integral
+  // template parameters.
+  const auto *DRE1 = cast(E1);
+  const auto *DRE2 = cast(E2);
+  return DRE1->isRValue() && DRE2->isRValue() &&
+ DRE1->getDecl() == DRE2->getDecl();
+}
+case ImplicitCastExprClass: {
+  // Peel off implicit casts.
+  while (true) {
+const auto *ICE1 = dyn_cast(E1);
+const auto *ICE2 = dyn_cast(E2);
+if (!ICE1 || !ICE2)
+  return false;
+if (ICE1->getCastKind() != ICE2->getCastKind())
+  return false;
+E1 = ICE1->getSubExpr()->IgnoreParens();
+E2 = ICE2->getSubExpr()->IgnoreParens();
+// The final cast must be one of these types.
+if (ICE1->getCastKind() == CK_LValueToRValue ||
+ICE1->getCastKind() == CK_ArrayToPointerDecay ||
+ICE1->getCastKind() == CK_FunctionToPointerDecay) {
+  break;
+}
+  }
+
+  const auto *DRE1 = dyn_cast(E1);
+  const auto *DRE2 = dyn_cast(E2);
+  if (DRE1 && DRE2)
+return declaresSameEntity(DRE1->getDecl(), DRE2->getDecl());
+
+  const auto *Ivar1 = dyn_cast(E1);
+  const auto *Ivar2 = dyn_cast(E2);
+  if (Ivar1 && Ivar2) {
+return Ivar1->isFreeIvar() && Ivar2->isFreeIvar() &&
+   declaresSameEntity(Ivar1->getDecl(), Ivar2->getDecl());
+  }
+
+  const auto *Array1 = dyn_cast(E1);
+  const auto *Array2 = dyn_cast(E2);
+  if (Array1 && Array2) {
+if (!isSameComparisonOperand(Array1->getBase(), Array2->g

  1   2   >