[PATCH] D47290: [Sema] -Wformat-pedantic only for NSInteger/NSUInteger %zu/%zi on Darwin

2018-05-23 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: test/FixIt/fixit-format-ios-nopedantic.m:21
+  printf("test 4: %zd %zd", getNSInteger(), getNSInteger());
+}

maybe i'm missing smth, but i don't see any verification in this test.


Repository:
  rC Clang

https://reviews.llvm.org/D47290



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


[PATCH] D38214: [analyzer] Fix crash on modeling of pointer arithmetic

2017-09-25 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL314141: [analyzer] Fix crash on modeling of pointer 
arithmetic (authored by alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D38214?vs=116455&id=116590#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D38214

Files:
  cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  cfe/trunk/test/Analysis/ptr-arith.cpp


Index: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -726,9 +726,11 @@
 if (Optional rInt = rhs.getAs()) {
   // If one of the operands is a symbol and the other is a constant,
   // build an expression for use by the constraint manager.
-  if (SymbolRef lSym = lhs.getAsLocSymbol(true))
-return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
-
+  if (SymbolRef lSym = lhs.getAsLocSymbol(true)) {
+if (BinaryOperator::isComparisonOp(op))
+  return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
+return UnknownVal();
+  }
   // Special case comparisons to NULL.
   // This must come after the test if the LHS is a symbol, which is used to
   // build constraints. The address of any non-symbolic region is 
guaranteed
Index: cfe/trunk/test/Analysis/ptr-arith.cpp
===
--- cfe/trunk/test/Analysis/ptr-arith.cpp
+++ cfe/trunk/test/Analysis/ptr-arith.cpp
@@ -111,3 +111,9 @@
   __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;
   return y == x;
 }
+
+// Bug 34374
+bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {
+  auto n = p - reinterpret_cast((__UINTPTR_TYPE__)1);
+  return n == m;
+}


Index: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -726,9 +726,11 @@
 if (Optional rInt = rhs.getAs()) {
   // If one of the operands is a symbol and the other is a constant,
   // build an expression for use by the constraint manager.
-  if (SymbolRef lSym = lhs.getAsLocSymbol(true))
-return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
-
+  if (SymbolRef lSym = lhs.getAsLocSymbol(true)) {
+if (BinaryOperator::isComparisonOp(op))
+  return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
+return UnknownVal();
+  }
   // Special case comparisons to NULL.
   // This must come after the test if the LHS is a symbol, which is used to
   // build constraints. The address of any non-symbolic region is guaranteed
Index: cfe/trunk/test/Analysis/ptr-arith.cpp
===
--- cfe/trunk/test/Analysis/ptr-arith.cpp
+++ cfe/trunk/test/Analysis/ptr-arith.cpp
@@ -111,3 +111,9 @@
   __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;
   return y == x;
 }
+
+// Bug 34374
+bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {
+  auto n = p - reinterpret_cast((__UINTPTR_TYPE__)1);
+  return n == m;
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38270: [clang] Add getUnsignedPointerDiffType method

2017-09-26 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.

C11 standard refers to the unsigned counterpart of the type ptrdiff_t 
in the paragraph 7.19.6 where it defines the format specifier %tu.
In Clang (in PrintfFormatString.cpp, lines 508-510) there is a FIXME for this 
case,
in particular, right now Clang doesn't diagnose %tu issues at all, i.e.
it doesn't emit any warnings on the code printf("%tu", 3.14).
In this diff we add a method getUnsignedPointerDiffType for getting the 
corresponding type
similarly to how it's already done in the other analogous cases (size_t, 
ssize_t, ptrdiff_t etc).
The code for printf diagnostics + new tests are supposed to be added by a 
separate diff.


Repository:
  rL LLVM

https://reviews.llvm.org/D38270

Files:
  include/clang/AST/ASTContext.h
  include/clang/Basic/TargetInfo.h
  lib/AST/ASTContext.cpp


Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -4571,6 +4571,12 @@
   return getFromTargetType(Target->getPtrDiffType(0));
 }
 
+/// getUnsignedPointerDiffType - Return the unique unsigned counterpart of
+// "ptrdiff_t" integer type.
+QualType ASTContext::getUnsignedPointerDiffType() const {
+  return getFromTargetType(Target->getUnsignedPtrDiffType(0));
+}
+
 /// \brief Return the unique type for "pid_t" defined in
 /// . We need this to compute the correct type for vfork().
 QualType ASTContext::getProcessIDType() const {
Index: include/clang/Basic/TargetInfo.h
===
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -248,6 +248,9 @@
   IntType getPtrDiffType(unsigned AddrSpace) const {
 return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
   }
+  IntType getUnsignedPtrDiffType(unsigned AddrSpace) const {
+return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
+  }
   IntType getIntPtrType() const { return IntPtrType; }
   IntType getUIntPtrType() const {
 return getCorrespondingUnsignedType(IntPtrType);
Index: include/clang/AST/ASTContext.h
===
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1489,6 +1489,10 @@
   /// . Pointer - pointer requires this (C99 6.5.6p9).
   QualType getPointerDiffType() const;
 
+  /// \brief Return the unique unsigned counterpart of 
+  /// "ptrdiff_t" integer type.
+  QualType getUnsignedPointerDiffType() const;
+
   /// \brief Return the unique type for "pid_t" defined in
   /// . We need this to compute the correct type for vfork().
   QualType getProcessIDType() const;


Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -4571,6 +4571,12 @@
   return getFromTargetType(Target->getPtrDiffType(0));
 }
 
+/// getUnsignedPointerDiffType - Return the unique unsigned counterpart of
+// "ptrdiff_t" integer type.
+QualType ASTContext::getUnsignedPointerDiffType() const {
+  return getFromTargetType(Target->getUnsignedPtrDiffType(0));
+}
+
 /// \brief Return the unique type for "pid_t" defined in
 /// . We need this to compute the correct type for vfork().
 QualType ASTContext::getProcessIDType() const {
Index: include/clang/Basic/TargetInfo.h
===
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -248,6 +248,9 @@
   IntType getPtrDiffType(unsigned AddrSpace) const {
 return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
   }
+  IntType getUnsignedPtrDiffType(unsigned AddrSpace) const {
+return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
+  }
   IntType getIntPtrType() const { return IntPtrType; }
   IntType getUIntPtrType() const {
 return getCorrespondingUnsignedType(IntPtrType);
Index: include/clang/AST/ASTContext.h
===
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1489,6 +1489,10 @@
   /// . Pointer - pointer requires this (C99 6.5.6p9).
   QualType getPointerDiffType() const;
 
+  /// \brief Return the unique unsigned counterpart of 
+  /// "ptrdiff_t" integer type.
+  QualType getUnsignedPointerDiffType() const;
+
   /// \brief Return the unique type for "pid_t" defined in
   /// . We need this to compute the correct type for vfork().
   QualType getProcessIDType() const;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38270: [clang] Add getUnsignedPointerDiffType method

2017-09-26 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 116635.
alexshap added a comment.

fix typo


Repository:
  rL LLVM

https://reviews.llvm.org/D38270

Files:
  include/clang/AST/ASTContext.h
  include/clang/Basic/TargetInfo.h
  lib/AST/ASTContext.cpp


Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -4571,6 +4571,12 @@
   return getFromTargetType(Target->getPtrDiffType(0));
 }
 
+/// getUnsignedPointerDiffType - Return the unique unsigned counterpart of
+/// "ptrdiff_t" integer type.
+QualType ASTContext::getUnsignedPointerDiffType() const {
+  return getFromTargetType(Target->getUnsignedPtrDiffType(0));
+}
+
 /// \brief Return the unique type for "pid_t" defined in
 /// . We need this to compute the correct type for vfork().
 QualType ASTContext::getProcessIDType() const {
Index: include/clang/Basic/TargetInfo.h
===
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -248,6 +248,9 @@
   IntType getPtrDiffType(unsigned AddrSpace) const {
 return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
   }
+  IntType getUnsignedPtrDiffType(unsigned AddrSpace) const {
+return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
+  }
   IntType getIntPtrType() const { return IntPtrType; }
   IntType getUIntPtrType() const {
 return getCorrespondingUnsignedType(IntPtrType);
Index: include/clang/AST/ASTContext.h
===
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1489,6 +1489,10 @@
   /// . Pointer - pointer requires this (C99 6.5.6p9).
   QualType getPointerDiffType() const;
 
+  /// \brief Return the unique unsigned counterpart of 
+  /// "ptrdiff_t" integer type.
+  QualType getUnsignedPointerDiffType() const;
+
   /// \brief Return the unique type for "pid_t" defined in
   /// . We need this to compute the correct type for vfork().
   QualType getProcessIDType() const;


Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -4571,6 +4571,12 @@
   return getFromTargetType(Target->getPtrDiffType(0));
 }
 
+/// getUnsignedPointerDiffType - Return the unique unsigned counterpart of
+/// "ptrdiff_t" integer type.
+QualType ASTContext::getUnsignedPointerDiffType() const {
+  return getFromTargetType(Target->getUnsignedPtrDiffType(0));
+}
+
 /// \brief Return the unique type for "pid_t" defined in
 /// . We need this to compute the correct type for vfork().
 QualType ASTContext::getProcessIDType() const {
Index: include/clang/Basic/TargetInfo.h
===
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -248,6 +248,9 @@
   IntType getPtrDiffType(unsigned AddrSpace) const {
 return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
   }
+  IntType getUnsignedPtrDiffType(unsigned AddrSpace) const {
+return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
+  }
   IntType getIntPtrType() const { return IntPtrType; }
   IntType getUIntPtrType() const {
 return getCorrespondingUnsignedType(IntPtrType);
Index: include/clang/AST/ASTContext.h
===
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1489,6 +1489,10 @@
   /// . Pointer - pointer requires this (C99 6.5.6p9).
   QualType getPointerDiffType() const;
 
+  /// \brief Return the unique unsigned counterpart of 
+  /// "ptrdiff_t" integer type.
+  QualType getUnsignedPointerDiffType() const;
+
   /// \brief Return the unique type for "pid_t" defined in
   /// . We need this to compute the correct type for vfork().
   QualType getProcessIDType() const;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38270: [clang] Add getUnsignedPointerDiffType method

2017-09-27 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 116894.
alexshap added a comment.

Address the comments


Repository:
  rL LLVM

https://reviews.llvm.org/D38270

Files:
  include/clang/AST/ASTContext.h
  include/clang/Basic/TargetInfo.h
  lib/AST/ASTContext.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Analysis/ScanfFormatString.cpp
  test/FixIt/format.m
  test/Sema/format-strings-scanf.c

Index: test/Sema/format-strings-scanf.c
===
--- test/Sema/format-strings-scanf.c
+++ test/Sema/format-strings-scanf.c
@@ -13,6 +13,16 @@
   unsigned short : (short)0,   \
   unsigned char : (signed char)0))
 typedef __SSIZE_TYPE__ ssize_t; 
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define __UNSIGNED_PTRDIFF_TYPE__  \
+  __typeof__(_Generic((__PTRDIFF_TYPE__)0, \
+  long long int : (unsigned long long int)0,   \
+  long int : (unsigned long int)0, \
+  int : (unsigned int)0,   \
+  short : (unsigned short)0,   \
+  signed char : (unsigned char)0))
+
 typedef struct _FILE FILE;
 typedef __WCHAR_TYPE__ wchar_t;
 
@@ -200,6 +210,26 @@
   scanf("%zn", &d3); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
 }
 
+void test_ptrdiff_t_types() {
+  __UNSIGNED_PTRDIFF_TYPE__ p1 = 0;
+  scanf("%tu", &p1); // No warning.
+
+  double d1 = 0.;
+  scanf("%tu", &d1); // expected-warning-re{{format specifies type 'unsigned ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ptrdiff_t p2 = 0;
+  scanf("%td", &p2); // No warning.
+  
+  double d2 = 0.;
+  scanf("%td", &d2); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ptrdiff_t p3 = 0;
+  scanf("%tn", &p3); // No warning.
+  
+  double d3 = 0.;
+  scanf("%tn", &d3); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+}
+
 void check_conditional_literal(char *s, int *i) {
   scanf(0 ? "%s" : "%d", i); // no warning
   scanf(1 ? "%s" : "%d", i); // expected-warning{{format specifies type 'char *'}}
Index: test/FixIt/format.m
===
--- test/FixIt/format.m
+++ test/FixIt/format.m
@@ -242,6 +242,19 @@
   // see the comment in PrintfSpecifier::fixType in PrintfFormatString.cpp.
 }
 
+void testPtrDiffTypes() {
+  printf("%tu", 0.f); // expected-warning-re{{format specifies type 'unsigned ptrdiff_t' (aka '{{.+}}') but the argument has type 'float'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
+  
+  printf("%td", 0.f); // expected-warning-re{{format specifies type 'ptrdiff_t' (aka '{{.+}}') but the argument has type 'float'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
+
+  short x;
+  printf("%tn", &x); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'short *'}}
+  // PrintfSpecifier::fixType doesn't handle %n, so a fix-it is not emitted,
+  // see the comment in PrintfSpecifier::fixType in PrintfFormatString.cpp.
+}
+
 void testEnum() {
   typedef enum {
 ImplicitA = 1,
Index: lib/Analysis/ScanfFormatString.cpp
===
--- lib/Analysis/ScanfFormatString.cpp
+++ lib/Analysis/ScanfFormatString.cpp
@@ -291,8 +291,8 @@
 case LengthModifier::AsSizeT:
   return ArgType::PtrTo(ArgType(Ctx.getSizeType(), "size_t"));
 case LengthModifier::AsPtrDiff:
-  // FIXME: Unsigned version of ptrdiff_t?
-  return ArgType();
+  return ArgType::PtrTo(
+  ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t"));
 case LengthModifier::AsLongDouble:
   // GNU extension.
   return ArgType::PtrTo(Ctx.UnsignedLongLongTy);
Index: lib/Analysis/PrintfFormatString.cpp
===
--- lib/Analysis/PrintfFormatString.cpp
+++ lib/Analysis/PrintfFormatString.cpp
@@ -505,9 +505,7 @@
? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
: ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
   case LengthModifier::AsPtrDiff:
-// FIXME: How to get the corresponding unsigned
-// version of ptrdiff_t?
-return ArgType();
+return ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t");
   case LengthModifier::AsAllocate:
   case LengthModifier::AsMAllocate:
   case LengthModifier::AsWide:
Index: lib/AST/ASTContext.cpp

[PATCH] D38270: [clang] Add getUnsignedPointerDiffType method

2017-09-28 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 117061.
alexshap added a comment.

Add positive tests


Repository:
  rL LLVM

https://reviews.llvm.org/D38270

Files:
  include/clang/AST/ASTContext.h
  include/clang/Basic/TargetInfo.h
  lib/AST/ASTContext.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Analysis/ScanfFormatString.cpp
  test/FixIt/format.m
  test/Sema/format-strings-scanf.c

Index: test/Sema/format-strings-scanf.c
===
--- test/Sema/format-strings-scanf.c
+++ test/Sema/format-strings-scanf.c
@@ -13,6 +13,16 @@
   unsigned short : (short)0,   \
   unsigned char : (signed char)0))
 typedef __SSIZE_TYPE__ ssize_t; 
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define __UNSIGNED_PTRDIFF_TYPE__  \
+  __typeof__(_Generic((__PTRDIFF_TYPE__)0, \
+  long long int : (unsigned long long int)0,   \
+  long int : (unsigned long int)0, \
+  int : (unsigned int)0,   \
+  short : (unsigned short)0,   \
+  signed char : (unsigned char)0))
+
 typedef struct _FILE FILE;
 typedef __WCHAR_TYPE__ wchar_t;
 
@@ -200,6 +210,26 @@
   scanf("%zn", &d3); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'double *'}}
 }
 
+void test_ptrdiff_t_types() {
+  __UNSIGNED_PTRDIFF_TYPE__ p1 = 0;
+  scanf("%tu", &p1); // No warning.
+
+  double d1 = 0.;
+  scanf("%tu", &d1); // expected-warning-re{{format specifies type 'unsigned ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ptrdiff_t p2 = 0;
+  scanf("%td", &p2); // No warning.
+  
+  double d2 = 0.;
+  scanf("%td", &d2); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+
+  ptrdiff_t p3 = 0;
+  scanf("%tn", &p3); // No warning.
+  
+  double d3 = 0.;
+  scanf("%tn", &d3); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'double *'}}
+}
+
 void check_conditional_literal(char *s, int *i) {
   scanf(0 ? "%s" : "%d", i); // no warning
   scanf(1 ? "%s" : "%d", i); // expected-warning{{format specifies type 'char *'}}
Index: test/FixIt/format.m
===
--- test/FixIt/format.m
+++ test/FixIt/format.m
@@ -242,6 +242,37 @@
   // see the comment in PrintfSpecifier::fixType in PrintfFormatString.cpp.
 }
 
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define __UNSIGNED_PTRDIFF_TYPE__  \
+  __typeof__(_Generic((__PTRDIFF_TYPE__)0, \
+  long long int : (unsigned long long int)0,   \
+  long int : (unsigned long int)0, \
+  int : (unsigned int)0,   \
+  short : (unsigned short)0,   \
+  signed char : (unsigned char)0))
+
+void testPtrDiffTypes() {
+  __UNSIGNED_PTRDIFF_TYPE__ p1 = 0;
+  printf("%tu", p1);  // No warning.
+
+  printf("%tu", 0.f); // expected-warning-re{{format specifies type 'unsigned ptrdiff_t' (aka '{{.+}}') but the argument has type 'float'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
+  
+  ptrdiff_t p2 = 0;
+  printf("%td", p2);  // No warning.
+
+  printf("%td", 0.f); // expected-warning-re{{format specifies type 'ptrdiff_t' (aka '{{.+}}') but the argument has type 'float'}}
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
+
+  ptrdiff_t p3 = 0;
+  printf("%tn", &p3); // No warning.
+
+  short x;
+  printf("%tn", &x); // expected-warning-re{{format specifies type 'ptrdiff_t *' (aka '{{.+}}') but the argument has type 'short *'}}
+  // PrintfSpecifier::fixType doesn't handle %n, so a fix-it is not emitted,
+  // see the comment in PrintfSpecifier::fixType in PrintfFormatString.cpp.
+}
+
 void testEnum() {
   typedef enum {
 ImplicitA = 1,
Index: lib/Analysis/ScanfFormatString.cpp
===
--- lib/Analysis/ScanfFormatString.cpp
+++ lib/Analysis/ScanfFormatString.cpp
@@ -291,8 +291,8 @@
 case LengthModifier::AsSizeT:
   return ArgType::PtrTo(ArgType(Ctx.getSizeType(), "size_t"));
 case LengthModifier::AsPtrDiff:
-  // FIXME: Unsigned version of ptrdiff_t?
-  return ArgType();
+  return ArgType::PtrTo(
+  ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t"));
 case LengthModifier::AsLongDouble:
   // GNU extension.
   return ArgType::PtrTo(Ctx.UnsignedLongL

[PATCH] D38270: [clang] Add getUnsignedPointerDiffType method

2017-09-28 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL314470: [clang] Add getUnsignedPointerDiffType method 
(authored by alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D38270?vs=117061&id=117075#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D38270

Files:
  cfe/trunk/include/clang/AST/ASTContext.h
  cfe/trunk/include/clang/Basic/TargetInfo.h
  cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/lib/Analysis/PrintfFormatString.cpp
  cfe/trunk/lib/Analysis/ScanfFormatString.cpp
  cfe/trunk/test/FixIt/format.m
  cfe/trunk/test/Sema/format-strings-scanf.c

Index: cfe/trunk/lib/AST/ASTContext.cpp
===
--- cfe/trunk/lib/AST/ASTContext.cpp
+++ cfe/trunk/lib/AST/ASTContext.cpp
@@ -4571,6 +4571,13 @@
   return getFromTargetType(Target->getPtrDiffType(0));
 }
 
+/// \brief Return the unique unsigned counterpart of "ptrdiff_t"
+/// integer type. The standard (C11 7.21.6.1p7) refers to this type
+/// in the definition of %tu format specifier.
+QualType ASTContext::getUnsignedPointerDiffType() const {
+  return getFromTargetType(Target->getUnsignedPtrDiffType(0));
+}
+
 /// \brief Return the unique type for "pid_t" defined in
 /// . We need this to compute the correct type for vfork().
 QualType ASTContext::getProcessIDType() const {
Index: cfe/trunk/lib/Analysis/ScanfFormatString.cpp
===
--- cfe/trunk/lib/Analysis/ScanfFormatString.cpp
+++ cfe/trunk/lib/Analysis/ScanfFormatString.cpp
@@ -291,8 +291,8 @@
 case LengthModifier::AsSizeT:
   return ArgType::PtrTo(ArgType(Ctx.getSizeType(), "size_t"));
 case LengthModifier::AsPtrDiff:
-  // FIXME: Unsigned version of ptrdiff_t?
-  return ArgType();
+  return ArgType::PtrTo(
+  ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t"));
 case LengthModifier::AsLongDouble:
   // GNU extension.
   return ArgType::PtrTo(Ctx.UnsignedLongLongTy);
Index: cfe/trunk/lib/Analysis/PrintfFormatString.cpp
===
--- cfe/trunk/lib/Analysis/PrintfFormatString.cpp
+++ cfe/trunk/lib/Analysis/PrintfFormatString.cpp
@@ -505,9 +505,7 @@
? ArgType(Ctx.UnsignedLongLongTy, "unsigned __int64")
: ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
   case LengthModifier::AsPtrDiff:
-// FIXME: How to get the corresponding unsigned
-// version of ptrdiff_t?
-return ArgType();
+return ArgType(Ctx.getUnsignedPointerDiffType(), "unsigned ptrdiff_t");
   case LengthModifier::AsAllocate:
   case LengthModifier::AsMAllocate:
   case LengthModifier::AsWide:
Index: cfe/trunk/include/clang/AST/ASTContext.h
===
--- cfe/trunk/include/clang/AST/ASTContext.h
+++ cfe/trunk/include/clang/AST/ASTContext.h
@@ -1489,6 +1489,11 @@
   /// . Pointer - pointer requires this (C99 6.5.6p9).
   QualType getPointerDiffType() const;
 
+  /// \brief Return the unique unsigned counterpart of "ptrdiff_t"
+  /// integer type. The standard (C11 7.21.6.1p7) refers to this type
+  /// in the definition of %tu format specifier.
+  QualType getUnsignedPointerDiffType() const;
+
   /// \brief Return the unique type for "pid_t" defined in
   /// . We need this to compute the correct type for vfork().
   QualType getProcessIDType() const;
Index: cfe/trunk/include/clang/Basic/TargetInfo.h
===
--- cfe/trunk/include/clang/Basic/TargetInfo.h
+++ cfe/trunk/include/clang/Basic/TargetInfo.h
@@ -248,6 +248,9 @@
   IntType getPtrDiffType(unsigned AddrSpace) const {
 return AddrSpace == 0 ? PtrDiffType : getPtrDiffTypeV(AddrSpace);
   }
+  IntType getUnsignedPtrDiffType(unsigned AddrSpace) const {
+return getCorrespondingUnsignedType(getPtrDiffType(AddrSpace));
+  }
   IntType getIntPtrType() const { return IntPtrType; }
   IntType getUIntPtrType() const {
 return getCorrespondingUnsignedType(IntPtrType);
Index: cfe/trunk/test/FixIt/format.m
===
--- cfe/trunk/test/FixIt/format.m
+++ cfe/trunk/test/FixIt/format.m
@@ -242,6 +242,37 @@
   // see the comment in PrintfSpecifier::fixType in PrintfFormatString.cpp.
 }
 
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#define __UNSIGNED_PTRDIFF_TYPE__  \
+  __typeof__(_Generic((__PTRDIFF_TYPE__)0, \
+  long long int : (unsigned long long int)0,   \
+  long int : (unsigned long int)0, \
+  int : (unsigned int)0,   \
+  short : (unsigned short)0,   \
+

[PATCH] D38859: [clang] Enable clang build with LLVM_BUILD_INSTRUMENTED without setting LLVM_PROFTDATA

2017-10-12 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.
Herald added a subscriber: mgorny.

At the moment if LLVM_BUILD_INSTRUMENTED is set to True 
one has to set LLVM_PROFTDATA even if it's not necessary (because of 
message(FATAL_ERROR ...)). 
Building instrumented Clang is useful even if one doesn't plan to use the 
target generate-profdata
(currently that target would use only 
llvm/tools/clang/utils/perf-training/cxx/hello_world.cpp as a source).
For example, one can run the instrumented version of Clang via a separate build 
system against a different codebase, 
collect the profiles and merge them by lllvm-profdata later.


Repository:
  rL LLVM

https://reviews.llvm.org/D38859

Files:
  utils/perf-training/CMakeLists.txt


Index: utils/perf-training/CMakeLists.txt
===
--- utils/perf-training/CMakeLists.txt
+++ utils/perf-training/CMakeLists.txt
@@ -30,13 +30,18 @@
   endif()
 
   if(NOT LLVM_PROFDATA)
-message(FATAL_ERROR "Must set LLVM_PROFDATA to point to llvm-profdata to 
use for merging PGO data")
+set(LLVM_PROFDATA ${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-profdata)
+message(STATUS "LLVM_PROFDATA is set to point to llvm-profdata built from 
the sources")
+set(GENERATE_PROFDATA_DEPENDS_ON_LLVM_PROFTDATA TRUE)
   endif()
-
+  
   add_custom_target(generate-profdata
 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py 
merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata 
${CMAKE_CURRENT_BINARY_DIR}
 COMMENT "Merging profdata"
 DEPENDS generate-profraw)
+  if (GENERATE_PROFDATA_DEPENDS_ON_LLVM_PROFTDATA)
+add_dependencies(generate-profdata llvm-profdata)
+  endif()
 endif()
 
 find_program(DTRACE dtrace)


Index: utils/perf-training/CMakeLists.txt
===
--- utils/perf-training/CMakeLists.txt
+++ utils/perf-training/CMakeLists.txt
@@ -30,13 +30,18 @@
   endif()
 
   if(NOT LLVM_PROFDATA)
-message(FATAL_ERROR "Must set LLVM_PROFDATA to point to llvm-profdata to use for merging PGO data")
+set(LLVM_PROFDATA ${LLVM_RUNTIME_OUTPUT_INTDIR}/llvm-profdata)
+message(STATUS "LLVM_PROFDATA is set to point to llvm-profdata built from the sources")
+set(GENERATE_PROFDATA_DEPENDS_ON_LLVM_PROFTDATA TRUE)
   endif()
-
+  
   add_custom_target(generate-profdata
 COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR}
 COMMENT "Merging profdata"
 DEPENDS generate-profraw)
+  if (GENERATE_PROFDATA_DEPENDS_ON_LLVM_PROFTDATA)
+add_dependencies(generate-profdata llvm-profdata)
+  endif()
 endif()
 
 find_program(DTRACE dtrace)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38859: [clang] Enable clang build with LLVM_BUILD_INSTRUMENTED without setting LLVM_PROFTDATA

2017-10-12 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

yeah, i agree, this is not a good idea. My thoughts were different - right now 
it's not particularly convenient that one has to specify LLVM_PROFDATA when 
it's not actually used by the build.
Maybe we can create the target "generate-profdata" only if LLVM_PROFDATA is set 
(but don't fail otherwise) ?


Repository:
  rL LLVM

https://reviews.llvm.org/D38859



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


[PATCH] D38859: [clang] Enable clang build with LLVM_BUILD_INSTRUMENTED without setting LLVM_PROFTDATA

2017-10-12 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 118868.

Repository:
  rL LLVM

https://reviews.llvm.org/D38859

Files:
  utils/perf-training/CMakeLists.txt


Index: utils/perf-training/CMakeLists.txt
===
--- utils/perf-training/CMakeLists.txt
+++ utils/perf-training/CMakeLists.txt
@@ -30,13 +30,13 @@
   endif()
 
   if(NOT LLVM_PROFDATA)
-message(FATAL_ERROR "Must set LLVM_PROFDATA to point to llvm-profdata to 
use for merging PGO data")
+message(STATUS "LLVM_PROFDATA needs to point to llvm-profdata to enable 
merging profdata")
+  else()
+add_custom_target(generate-profdata
+  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py 
merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata 
${CMAKE_CURRENT_BINARY_DIR}
+  COMMENT "Merging profdata"
+  DEPENDS generate-profraw)
   endif()
-
-  add_custom_target(generate-profdata
-COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py 
merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata 
${CMAKE_CURRENT_BINARY_DIR}
-COMMENT "Merging profdata"
-DEPENDS generate-profraw)
 endif()
 
 find_program(DTRACE dtrace)


Index: utils/perf-training/CMakeLists.txt
===
--- utils/perf-training/CMakeLists.txt
+++ utils/perf-training/CMakeLists.txt
@@ -30,13 +30,13 @@
   endif()
 
   if(NOT LLVM_PROFDATA)
-message(FATAL_ERROR "Must set LLVM_PROFDATA to point to llvm-profdata to use for merging PGO data")
+message(STATUS "LLVM_PROFDATA needs to point to llvm-profdata to enable merging profdata")
+  else()
+add_custom_target(generate-profdata
+  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR}
+  COMMENT "Merging profdata"
+  DEPENDS generate-profraw)
   endif()
-
-  add_custom_target(generate-profdata
-COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR}
-COMMENT "Merging profdata"
-DEPENDS generate-profraw)
 endif()
 
 find_program(DTRACE dtrace)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38859: [clang] Enable clang build with LLVM_BUILD_INSTRUMENTED without setting LLVM_PROFTDATA

2017-10-12 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 118869.
alexshap added a comment.

Update the wording


Repository:
  rL LLVM

https://reviews.llvm.org/D38859

Files:
  utils/perf-training/CMakeLists.txt


Index: utils/perf-training/CMakeLists.txt
===
--- utils/perf-training/CMakeLists.txt
+++ utils/perf-training/CMakeLists.txt
@@ -30,13 +30,13 @@
   endif()
 
   if(NOT LLVM_PROFDATA)
-message(FATAL_ERROR "Must set LLVM_PROFDATA to point to llvm-profdata to 
use for merging PGO data")
+message(STATUS "To enable merging PGO data LLVM_PROFDATA has to point to 
llvm-profdata")
+  else()
+add_custom_target(generate-profdata
+  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py 
merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata 
${CMAKE_CURRENT_BINARY_DIR}
+  COMMENT "Merging profdata"
+  DEPENDS generate-profraw)
   endif()
-
-  add_custom_target(generate-profdata
-COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py 
merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata 
${CMAKE_CURRENT_BINARY_DIR}
-COMMENT "Merging profdata"
-DEPENDS generate-profraw)
 endif()
 
 find_program(DTRACE dtrace)


Index: utils/perf-training/CMakeLists.txt
===
--- utils/perf-training/CMakeLists.txt
+++ utils/perf-training/CMakeLists.txt
@@ -30,13 +30,13 @@
   endif()
 
   if(NOT LLVM_PROFDATA)
-message(FATAL_ERROR "Must set LLVM_PROFDATA to point to llvm-profdata to use for merging PGO data")
+message(STATUS "To enable merging PGO data LLVM_PROFDATA has to point to llvm-profdata")
+  else()
+add_custom_target(generate-profdata
+  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR}
+  COMMENT "Merging profdata"
+  DEPENDS generate-profraw)
   endif()
-
-  add_custom_target(generate-profdata
-COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR}
-COMMENT "Merging profdata"
-DEPENDS generate-profraw)
 endif()
 
 find_program(DTRACE dtrace)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38859: [clang] Enable clang build with LLVM_BUILD_INSTRUMENTED without setting LLVM_PROFTDATA

2017-10-12 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL315665: [clang] Enable clang build with 
LLVM_BUILD_INSTRUMENTED without setting… (authored by alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D38859?vs=118869&id=118881#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D38859

Files:
  cfe/trunk/utils/perf-training/CMakeLists.txt


Index: cfe/trunk/utils/perf-training/CMakeLists.txt
===
--- cfe/trunk/utils/perf-training/CMakeLists.txt
+++ cfe/trunk/utils/perf-training/CMakeLists.txt
@@ -30,13 +30,13 @@
   endif()
 
   if(NOT LLVM_PROFDATA)
-message(FATAL_ERROR "Must set LLVM_PROFDATA to point to llvm-profdata to 
use for merging PGO data")
+message(STATUS "To enable merging PGO data LLVM_PROFDATA has to point to 
llvm-profdata")
+  else()
+add_custom_target(generate-profdata
+  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py 
merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata 
${CMAKE_CURRENT_BINARY_DIR}
+  COMMENT "Merging profdata"
+  DEPENDS generate-profraw)
   endif()
-
-  add_custom_target(generate-profdata
-COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py 
merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata 
${CMAKE_CURRENT_BINARY_DIR}
-COMMENT "Merging profdata"
-DEPENDS generate-profraw)
 endif()
 
 find_program(DTRACE dtrace)


Index: cfe/trunk/utils/perf-training/CMakeLists.txt
===
--- cfe/trunk/utils/perf-training/CMakeLists.txt
+++ cfe/trunk/utils/perf-training/CMakeLists.txt
@@ -30,13 +30,13 @@
   endif()
 
   if(NOT LLVM_PROFDATA)
-message(FATAL_ERROR "Must set LLVM_PROFDATA to point to llvm-profdata to use for merging PGO data")
+message(STATUS "To enable merging PGO data LLVM_PROFDATA has to point to llvm-profdata")
+  else()
+add_custom_target(generate-profdata
+  COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR}
+  COMMENT "Merging profdata"
+  DEPENDS generate-profraw)
   endif()
-
-  add_custom_target(generate-profdata
-COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/perf-helper.py merge ${LLVM_PROFDATA} ${CMAKE_CURRENT_BINARY_DIR}/clang.profdata ${CMAKE_CURRENT_BINARY_DIR}
-COMMENT "Merging profdata"
-DEPENDS generate-profraw)
 endif()
 
 find_program(DTRACE dtrace)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39174: [analyzer] Fix handling of labels getLValueElement

2017-10-22 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.
Herald added subscribers: szepet, xazax.hun.

In getLValueElement Base may represent the address of a label (as in the 
newly-added test case),
in this case it's not a loc::MemRegionVal and Base.castAs() 
triggers an assert.

Test plan: make check-all


Repository:
  rL LLVM

https://reviews.llvm.org/D39174

Files:
  lib/StaticAnalyzer/Core/Store.cpp
  test/Analysis/ptr-arith.c


Index: test/Analysis/ptr-arith.c
===
--- test/Analysis/ptr-arith.c
+++ test/Analysis/ptr-arith.c
@@ -342,3 +342,8 @@
   clang_analyzer_eval(*ptr3 == 'a'); // expected-warning{{UNKNOWN}}
 }
 
+void test_no_crash_on_pointer_to_label() {
+  char *a = &&label;
+  a[0] = 0;
+label:;
+}
Index: lib/StaticAnalyzer/Core/Store.cpp
===
--- lib/StaticAnalyzer/Core/Store.cpp
+++ lib/StaticAnalyzer/Core/Store.cpp
@@ -440,7 +440,10 @@
   //  value. See also the similar FIXME in getLValueFieldOrIvar().
   if (Base.isUnknownOrUndef() || Base.getAs())
 return Base;
-
+  
+  if (Base.getAs())
+return UnknownVal();
+  
   const SubRegion *BaseRegion =
   Base.castAs().getRegionAs();
 


Index: test/Analysis/ptr-arith.c
===
--- test/Analysis/ptr-arith.c
+++ test/Analysis/ptr-arith.c
@@ -342,3 +342,8 @@
   clang_analyzer_eval(*ptr3 == 'a'); // expected-warning{{UNKNOWN}}
 }
 
+void test_no_crash_on_pointer_to_label() {
+  char *a = &&label;
+  a[0] = 0;
+label:;
+}
Index: lib/StaticAnalyzer/Core/Store.cpp
===
--- lib/StaticAnalyzer/Core/Store.cpp
+++ lib/StaticAnalyzer/Core/Store.cpp
@@ -440,7 +440,10 @@
   //  value. See also the similar FIXME in getLValueFieldOrIvar().
   if (Base.isUnknownOrUndef() || Base.getAs())
 return Base;
-
+  
+  if (Base.getAs())
+return UnknownVal();
+  
   const SubRegion *BaseRegion =
   Base.castAs().getRegionAs();
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39174: [analyzer] Fix handling of labels in getLValueElement

2017-10-23 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL316399: [analyzer] Fix handling of labels in 
getLValueElement (authored by alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D39174?vs=119808&id=119972#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D39174

Files:
  cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp
  cfe/trunk/test/Analysis/ptr-arith.c


Index: cfe/trunk/test/Analysis/ptr-arith.c
===
--- cfe/trunk/test/Analysis/ptr-arith.c
+++ cfe/trunk/test/Analysis/ptr-arith.c
@@ -342,3 +342,8 @@
   clang_analyzer_eval(*ptr3 == 'a'); // expected-warning{{UNKNOWN}}
 }
 
+void test_no_crash_on_pointer_to_label() {
+  char *a = &&label;
+  a[0] = 0;
+label:;
+}
Index: cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp
@@ -440,7 +440,10 @@
   //  value. See also the similar FIXME in getLValueFieldOrIvar().
   if (Base.isUnknownOrUndef() || Base.getAs())
 return Base;
-
+  
+  if (Base.getAs())
+return UnknownVal();
+  
   const SubRegion *BaseRegion =
   Base.castAs().getRegionAs();
 


Index: cfe/trunk/test/Analysis/ptr-arith.c
===
--- cfe/trunk/test/Analysis/ptr-arith.c
+++ cfe/trunk/test/Analysis/ptr-arith.c
@@ -342,3 +342,8 @@
   clang_analyzer_eval(*ptr3 == 'a'); // expected-warning{{UNKNOWN}}
 }
 
+void test_no_crash_on_pointer_to_label() {
+  char *a = &&label;
+  a[0] = 0;
+label:;
+}
Index: cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/Store.cpp
@@ -440,7 +440,10 @@
   //  value. See also the similar FIXME in getLValueFieldOrIvar().
   if (Base.isUnknownOrUndef() || Base.getAs())
 return Base;
-
+  
+  if (Base.getAs())
+return UnknownVal();
+  
   const SubRegion *BaseRegion =
   Base.castAs().getRegionAs();
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D33470: [clang-tidy] Add misc-default-numerics

2017-05-25 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: clang-tidy/misc/DefaultNumericsCheck.h:20
+/// This check flags usages of ``std::numeric_limits::{min,max}()`` for
+/// unspecialized types. It is dangerous because it returns T(), which might is
+/// rarely minimum or maximum for this type.

nit: (feel free to correct me) 
replace 
"which might is ..." 
with 
"which rarely might be minimum or maximum for this type" 


https://reviews.llvm.org/D33470



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


[PATCH] D33976: [clang] Fix format specifiers fixits

2017-06-06 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.

This diff fixes printf "fixits" in the case when there is a wrapping macro and
the format string needs multiple replacements. 
In the presence of a macro there was an extra logic in EditedSource.cpp
to handle multiple uses of the same macro argument 
(see the old comment inside EditedSource::canInsertInOffset)
which was mistriggering when the argument was used only once 
but required multiple adjustments), as a result the "fixit" was breaking down 
the format string
by dropping the second format specifier, i.e. 
Log1("test 4: %s %s", getNSInteger(), getNSInteger()) 
was getting replaced with 
Log1("test 4: %ld ", (long)getNSInteger(), (long)getNSInteger()) 
(if one removed the macro and used printf directly it would work fine).
In this diff we track the location where the macro argument is used and 
(as it was before) the modifications originating from all the locations except 
the first one are rejected,
but multiple changes are allowed.

Test plan: make check-all


Repository:
  rL LLVM

https://reviews.llvm.org/D33976

Files:
  include/clang/Edit/EditedSource.h
  lib/Edit/EditedSource.cpp
  test/FixIt/fixit-format-darwin.m

Index: test/FixIt/fixit-format-darwin.m
===
--- test/FixIt/fixit-format-darwin.m
+++ test/FixIt/fixit-format-darwin.m
@@ -0,0 +1,60 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -Wformat -fixit %t
+// RUN: grep -v CHECK %t > %t2
+// RUN: FileCheck -input-file=%t2 %s
+
+/* This is a test of code modifications created by darwin format fix-its hints 
+   that are provided as part of warning */
+
+int printf(const char * restrict, ...);
+
+#if __LP64__
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+#else
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+#endif
+NSInteger getNSInteger();
+NSUInteger getNSUInteger();
+
+#define Log1(...) \
+do { \
+  printf(__VA_ARGS__); \
+} while (0)
+
+#define Log2(...) \
+do { \
+  printf(__VA_ARGS__); \
+  printf(__VA_ARGS__); \
+} while (0) \
+
+#define Log3(X, Y, Z) \
+do { \
+  printf(X, Y); \
+  printf(X, Z); \
+} while (0) \
+
+void test() {
+  printf("test 1: %s", getNSInteger()); 
+  // CHECK: printf("test 1: %ld", (long)getNSInteger());
+  printf("test 2: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: printf("test 2: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+  
+  Log1("test 3: %s", getNSInteger());
+  // CHECK: Log1("test 3: %ld", (long)getNSInteger());
+  Log1("test 4: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Log1("test 4: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+  
+  Log2("test 5: %s", getNSInteger());
+  // CHECK: Log2("test 5: %ld", (long)getNSInteger()); 
+  Log2("test 6: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Log2("test 6: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+  
+  // Aritificial test to check that X (in Log3(X, Y, Z))
+  // is modified only according to the diagnostics
+  // for the first printf and the modification caused 
+  // by the second printf is dropped
+  Log3("test 7: %s", getNSInteger(), getNSUInteger());
+  // CHECK: Log3("test 7: %ld", (long)getNSInteger(), (unsigned long)getNSUInteger());
+}
Index: lib/Edit/EditedSource.cpp
===
--- lib/Edit/EditedSource.cpp
+++ lib/Edit/EditedSource.cpp
@@ -25,30 +25,28 @@
 
 void EditedSource::deconstructMacroArgLoc(SourceLocation Loc,
   SourceLocation &ExpansionLoc,
-  IdentifierInfo *&II) {
+  MacroArgUse &ArgUse) {
   assert(SourceMgr.isMacroArgExpansion(Loc));
   SourceLocation DefArgLoc = SourceMgr.getImmediateExpansionRange(Loc).first;
   ExpansionLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
   SmallString<20> Buf;
   StringRef ArgName = Lexer::getSpelling(SourceMgr.getSpellingLoc(DefArgLoc),
  Buf, SourceMgr, LangOpts);
-  II = nullptr;
-  if (!ArgName.empty()) {
-II = &IdentTable.get(ArgName);
-  }
+  ArgUse = {nullptr, SourceLocation()};
+  if (!ArgName.empty())
+ArgUse = {&IdentTable.get(ArgName), SourceMgr.getSpellingLoc(DefArgLoc)};
 }
 
 void EditedSource::startingCommit() {}
 
 void EditedSource::finishedCommit() {
   for (auto &ExpArg : CurrCommitMacroArgExps) {
 SourceLocation ExpLoc;
-IdentifierInfo *II;
-std::tie(ExpLoc, II) = ExpArg;
-auto &ArgNames = ExpansionToArgMap[ExpLoc.getRawEncoding()];
-if (std::find(ArgNames.begin(), ArgNames.end(), II) == ArgNames.end()) {
-  ArgNames.push_back(II);
-}
+MacroArgUse ArgUse;
+std::tie(ExpLoc, ArgUse) = ExpArg;
+auto &ArgUses = ExpansionToArgMap[ExpLoc.getRawEncoding()];
+if (std::find(ArgUses.begin(), ArgUses.end(), ArgUse) == ArgUses.end())
+  ArgUses.push_back(ArgUse);
   }
   CurrCommit

[PATCH] D33976: [clang] Fix format specifiers fixits

2017-06-08 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

@mehdi_amini , thanks, i see, regarding the "opposite issue" - probably an 
example / test case would be helpful, that looks like a separate issue.
Thanks for adding @ahatanak and @arphaman, that would be wonderful if smb could 
look at this diff (which, besides the fix, adds tests)


Repository:
  rL LLVM

https://reviews.llvm.org/D33976



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


[PATCH] D33976: [clang] Fix format specifiers fixits

2017-06-08 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 101962.
alexshap added a comment.

Address comments


Repository:
  rL LLVM

https://reviews.llvm.org/D33976

Files:
  include/clang/Edit/EditedSource.h
  lib/Edit/EditedSource.cpp
  test/FixIt/fixit-format-darwin.m

Index: test/FixIt/fixit-format-darwin.m
===
--- test/FixIt/fixit-format-darwin.m
+++ test/FixIt/fixit-format-darwin.m
@@ -0,0 +1,59 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -Wformat -fixit %t
+// RUN: grep -v CHECK %t | FileCheck %s
+
+/* This is a test of code modifications created by darwin format fix-its hints 
+   that are provided as part of warning */
+
+int printf(const char * restrict, ...);
+
+#if __LP64__
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+#else
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+#endif
+NSInteger getNSInteger();
+NSUInteger getNSUInteger();
+
+#define Log1(...) \
+do { \
+  printf(__VA_ARGS__); \
+} while (0)
+
+#define Log2(...) \
+do { \
+  printf(__VA_ARGS__); \
+  printf(__VA_ARGS__); \
+} while (0) \
+
+#define Log3(X, Y, Z) \
+do { \
+  printf(X, Y); \
+  printf(X, Z); \
+} while (0) \
+
+void test() {
+  printf("test 1: %s", getNSInteger()); 
+  // CHECK: printf("test 1: %ld", (long)getNSInteger());
+  printf("test 2: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: printf("test 2: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+  
+  Log1("test 3: %s", getNSInteger());
+  // CHECK: Log1("test 3: %ld", (long)getNSInteger());
+  Log1("test 4: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Log1("test 4: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+  
+  Log2("test 5: %s", getNSInteger());
+  // CHECK: Log2("test 5: %ld", (long)getNSInteger()); 
+  Log2("test 6: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Log2("test 6: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+  
+  // Artificial test to check that X (in Log3(X, Y, Z))
+  // is modified only according to the diagnostics
+  // for the first printf and the modification caused 
+  // by the second printf is dropped.
+  Log3("test 7: %s", getNSInteger(), getNSUInteger());
+  // CHECK: Log3("test 7: %ld", (long)getNSInteger(), (unsigned long)getNSUInteger());
+}
Index: lib/Edit/EditedSource.cpp
===
--- lib/Edit/EditedSource.cpp
+++ lib/Edit/EditedSource.cpp
@@ -25,30 +25,28 @@
 
 void EditedSource::deconstructMacroArgLoc(SourceLocation Loc,
   SourceLocation &ExpansionLoc,
-  IdentifierInfo *&II) {
+  MacroArgUse &ArgUse) {
   assert(SourceMgr.isMacroArgExpansion(Loc));
   SourceLocation DefArgLoc = SourceMgr.getImmediateExpansionRange(Loc).first;
   ExpansionLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
   SmallString<20> Buf;
   StringRef ArgName = Lexer::getSpelling(SourceMgr.getSpellingLoc(DefArgLoc),
  Buf, SourceMgr, LangOpts);
-  II = nullptr;
-  if (!ArgName.empty()) {
-II = &IdentTable.get(ArgName);
-  }
+  ArgUse = {nullptr, SourceLocation()};
+  if (!ArgName.empty())
+ArgUse = {&IdentTable.get(ArgName), SourceMgr.getSpellingLoc(DefArgLoc)};
 }
 
 void EditedSource::startingCommit() {}
 
 void EditedSource::finishedCommit() {
   for (auto &ExpArg : CurrCommitMacroArgExps) {
 SourceLocation ExpLoc;
-IdentifierInfo *II;
-std::tie(ExpLoc, II) = ExpArg;
-auto &ArgNames = ExpansionToArgMap[ExpLoc.getRawEncoding()];
-if (std::find(ArgNames.begin(), ArgNames.end(), II) == ArgNames.end()) {
-  ArgNames.push_back(II);
-}
+MacroArgUse ArgUse;
+std::tie(ExpLoc, ArgUse) = ExpArg;
+auto &ArgUses = ExpansionToArgMap[ExpLoc.getRawEncoding()];
+if (std::find(ArgUses.begin(), ArgUses.end(), ArgUse) == ArgUses.end())
+  ArgUses.push_back(ArgUse);
   }
   CurrCommitMacroArgExps.clear();
 }
@@ -66,12 +64,15 @@
   }
 
   if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
-IdentifierInfo *II;
 SourceLocation ExpLoc;
-deconstructMacroArgLoc(OrigLoc, ExpLoc, II);
+MacroArgUse ArgUse;
+deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
 auto I = ExpansionToArgMap.find(ExpLoc.getRawEncoding());
 if (I != ExpansionToArgMap.end() &&
-std::find(I->second.begin(), I->second.end(), II) != I->second.end()) {
+std::find_if(
+I->second.begin(), I->second.end(), [&](const MacroArgUse &U) {
+  return ArgUse.first == U.first && ArgUse.second != U.second;
+}) != I->second.end()) {
   // Trying to write in a macro argument input that has already been
   // written by a previous commit for another expansion of the same macro
   // argument name. For example:
@@ -101,11 +102,11 @@
 return true;
 
   if (SourceMgr.isMacroArgExpansion

[PATCH] D33976: [clang] Fix format specifiers fixits

2017-06-08 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL305018: [clang] Fix format specifiers fixits (authored by 
alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D33976?vs=101962&id=101964#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D33976

Files:
  cfe/trunk/include/clang/Edit/EditedSource.h
  cfe/trunk/lib/Edit/EditedSource.cpp
  cfe/trunk/test/FixIt/fixit-format-darwin.m

Index: cfe/trunk/test/FixIt/fixit-format-darwin.m
===
--- cfe/trunk/test/FixIt/fixit-format-darwin.m
+++ cfe/trunk/test/FixIt/fixit-format-darwin.m
@@ -0,0 +1,59 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -fsyntax-only -fblocks -Wformat -fixit %t
+// RUN: grep -v CHECK %t | FileCheck %s
+
+/* This is a test of code modifications created by darwin format fix-its hints 
+   that are provided as part of warning */
+
+int printf(const char * restrict, ...);
+
+#if __LP64__
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+#else
+typedef int NSInteger;
+typedef unsigned int NSUInteger;
+#endif
+NSInteger getNSInteger();
+NSUInteger getNSUInteger();
+
+#define Log1(...) \
+do { \
+  printf(__VA_ARGS__); \
+} while (0)
+
+#define Log2(...) \
+do { \
+  printf(__VA_ARGS__); \
+  printf(__VA_ARGS__); \
+} while (0) \
+
+#define Log3(X, Y, Z) \
+do { \
+  printf(X, Y); \
+  printf(X, Z); \
+} while (0) \
+
+void test() {
+  printf("test 1: %s", getNSInteger()); 
+  // CHECK: printf("test 1: %ld", (long)getNSInteger());
+  printf("test 2: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: printf("test 2: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+  
+  Log1("test 3: %s", getNSInteger());
+  // CHECK: Log1("test 3: %ld", (long)getNSInteger());
+  Log1("test 4: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Log1("test 4: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+  
+  Log2("test 5: %s", getNSInteger());
+  // CHECK: Log2("test 5: %ld", (long)getNSInteger()); 
+  Log2("test 6: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Log2("test 6: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+  
+  // Artificial test to check that X (in Log3(X, Y, Z))
+  // is modified only according to the diagnostics
+  // for the first printf and the modification caused 
+  // by the second printf is dropped.
+  Log3("test 7: %s", getNSInteger(), getNSUInteger());
+  // CHECK: Log3("test 7: %ld", (long)getNSInteger(), (unsigned long)getNSUInteger());
+}
Index: cfe/trunk/lib/Edit/EditedSource.cpp
===
--- cfe/trunk/lib/Edit/EditedSource.cpp
+++ cfe/trunk/lib/Edit/EditedSource.cpp
@@ -25,30 +25,28 @@
 
 void EditedSource::deconstructMacroArgLoc(SourceLocation Loc,
   SourceLocation &ExpansionLoc,
-  IdentifierInfo *&II) {
+  MacroArgUse &ArgUse) {
   assert(SourceMgr.isMacroArgExpansion(Loc));
   SourceLocation DefArgLoc = SourceMgr.getImmediateExpansionRange(Loc).first;
   ExpansionLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
   SmallString<20> Buf;
   StringRef ArgName = Lexer::getSpelling(SourceMgr.getSpellingLoc(DefArgLoc),
  Buf, SourceMgr, LangOpts);
-  II = nullptr;
-  if (!ArgName.empty()) {
-II = &IdentTable.get(ArgName);
-  }
+  ArgUse = {nullptr, SourceLocation()};
+  if (!ArgName.empty())
+ArgUse = {&IdentTable.get(ArgName), SourceMgr.getSpellingLoc(DefArgLoc)};
 }
 
 void EditedSource::startingCommit() {}
 
 void EditedSource::finishedCommit() {
   for (auto &ExpArg : CurrCommitMacroArgExps) {
 SourceLocation ExpLoc;
-IdentifierInfo *II;
-std::tie(ExpLoc, II) = ExpArg;
-auto &ArgNames = ExpansionToArgMap[ExpLoc.getRawEncoding()];
-if (std::find(ArgNames.begin(), ArgNames.end(), II) == ArgNames.end()) {
-  ArgNames.push_back(II);
-}
+MacroArgUse ArgUse;
+std::tie(ExpLoc, ArgUse) = ExpArg;
+auto &ArgUses = ExpansionToArgMap[ExpLoc.getRawEncoding()];
+if (std::find(ArgUses.begin(), ArgUses.end(), ArgUse) == ArgUses.end())
+  ArgUses.push_back(ArgUse);
   }
   CurrCommitMacroArgExps.clear();
 }
@@ -66,12 +64,15 @@
   }
 
   if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
-IdentifierInfo *II;
 SourceLocation ExpLoc;
-deconstructMacroArgLoc(OrigLoc, ExpLoc, II);
+MacroArgUse ArgUse;
+deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
 auto I = ExpansionToArgMap.find(ExpLoc.getRawEncoding());
 if (I != ExpansionToArgMap.end() &&
-std::find(I->second.begin(), I->second.end(), II) != I->second.end()) {
+std::find_if(
+I->second.begin(), I->second.end(), [&](const MacroArgUse &U) {
+  return ArgUse.first == U.first && ArgUse.second != U.second;
+}) != I->second.end()) {
   // Trying to writ

[PATCH] D34066: [clang] Cleanup fixit.c

2017-06-09 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.

This diff removes temporary file t2 in fixit.c and updates the test command 
accordingly.
NFC.


Repository:
  rL LLVM

https://reviews.llvm.org/D34066

Files:
  fixit.c


Index: fixit.c
===
--- fixit.c
+++ fixit.c
@@ -1,9 +1,8 @@
 // RUN: %clang_cc1 -pedantic -Wunused-label -verify -x c %s
 // RUN: cp %s %t
 // RUN: not %clang_cc1 -pedantic -Wunused-label -fixit -x c %t
-// RUN: grep -v CHECK %t > %t2
 // RUN: %clang_cc1 -pedantic -Wunused-label -Werror -x c %t
-// RUN: FileCheck -input-file=%t2 %t
+// RUN: grep -v CHECK %t | FileCheck %t
 
 /* This is a test of the various code modification hints that are
provided as part of warning or extension diagnostics. All of the


Index: fixit.c
===
--- fixit.c
+++ fixit.c
@@ -1,9 +1,8 @@
 // RUN: %clang_cc1 -pedantic -Wunused-label -verify -x c %s
 // RUN: cp %s %t
 // RUN: not %clang_cc1 -pedantic -Wunused-label -fixit -x c %t
-// RUN: grep -v CHECK %t > %t2
 // RUN: %clang_cc1 -pedantic -Wunused-label -Werror -x c %t
-// RUN: FileCheck -input-file=%t2 %t
+// RUN: grep -v CHECK %t | FileCheck %t
 
 /* This is a test of the various code modification hints that are
provided as part of warning or extension diagnostics. All of the
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34066: [clang] Cleanup fixit.c

2017-06-09 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL305124: [clang] Cleanup fixit.c (authored by alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D34066?vs=102076&id=102079#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D34066

Files:
  cfe/trunk/test/FixIt/fixit.c


Index: cfe/trunk/test/FixIt/fixit.c
===
--- cfe/trunk/test/FixIt/fixit.c
+++ cfe/trunk/test/FixIt/fixit.c
@@ -1,9 +1,8 @@
 // RUN: %clang_cc1 -pedantic -Wunused-label -verify -x c %s
 // RUN: cp %s %t
 // RUN: not %clang_cc1 -pedantic -Wunused-label -fixit -x c %t
-// RUN: grep -v CHECK %t > %t2
 // RUN: %clang_cc1 -pedantic -Wunused-label -Werror -x c %t
-// RUN: FileCheck -input-file=%t2 %t
+// RUN: grep -v CHECK %t | FileCheck %t
 
 /* This is a test of the various code modification hints that are
provided as part of warning or extension diagnostics. All of the


Index: cfe/trunk/test/FixIt/fixit.c
===
--- cfe/trunk/test/FixIt/fixit.c
+++ cfe/trunk/test/FixIt/fixit.c
@@ -1,9 +1,8 @@
 // RUN: %clang_cc1 -pedantic -Wunused-label -verify -x c %s
 // RUN: cp %s %t
 // RUN: not %clang_cc1 -pedantic -Wunused-label -fixit -x c %t
-// RUN: grep -v CHECK %t > %t2
 // RUN: %clang_cc1 -pedantic -Wunused-label -Werror -x c %t
-// RUN: FileCheck -input-file=%t2 %t
+// RUN: grep -v CHECK %t | FileCheck %t
 
 /* This is a test of the various code modification hints that are
provided as part of warning or extension diagnostics. All of the
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34268: [clang] Fix format specifiers fixits for nested macros

2017-06-15 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.

ExpansionLoc was previously calculated incorrectly in the case of 
nested macros expansions. In this diff we build the stack of expansions where 
the last one
is the actual expansion (in the source code) which should be used for grouping 
together 
the edits. The definition of MacroArgUse is adjusted accordingly: now it's 
essentially the stack of expansions plus
the location of argument use inside the top-most macro. 
This diff fixes https://bugs.llvm.org/show_bug.cgi?id=33447 .

Test plan: make check-all


Repository:
  rL LLVM

https://reviews.llvm.org/D34268

Files:
  include/clang/Edit/EditedSource.h
  lib/Edit/EditedSource.cpp
  test/FixIt/fixit-format-darwin.m

Index: test/FixIt/fixit-format-darwin.m
===
--- test/FixIt/fixit-format-darwin.m
+++ test/FixIt/fixit-format-darwin.m
@@ -57,3 +57,20 @@
   Log3("test 7: %s", getNSInteger(), getNSUInteger());
   // CHECK: Log3("test 7: %ld", (long)getNSInteger(), (unsigned long)getNSUInteger());
 }
+
+#define Outer1(...) \
+do { \
+  printf(__VA_ARGS__); \
+} while (0)
+
+#define Outer2(...) \
+do { \
+  Outer1(__VA_ARGS__); Outer1(__VA_ARGS__); \
+} while (0)
+
+void radar33447() {
+  Outer2("test 8: %s", getNSInteger());  
+  // CHECK: Outer2("test 8: %ld", (long)getNSInteger());
+  Outer2("test 9: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Outer2("test 9: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+}
Index: lib/Edit/EditedSource.cpp
===
--- lib/Edit/EditedSource.cpp
+++ lib/Edit/EditedSource.cpp
@@ -24,17 +24,22 @@
 }
 
 void EditedSource::deconstructMacroArgLoc(SourceLocation Loc,
-  SourceLocation &ExpansionLoc,
   MacroArgUse &ArgUse) {
   assert(SourceMgr.isMacroArgExpansion(Loc));
   SourceLocation DefArgLoc = SourceMgr.getImmediateExpansionRange(Loc).first;
-  ExpansionLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
+  SmallVector ExpansionStack;
+  ExpansionStack.push_back(
+  SourceMgr.getImmediateExpansionRange(DefArgLoc).first);
+  while (SourceMgr.isMacroBodyExpansion(ExpansionStack.back()))
+ExpansionStack.push_back(
+SourceMgr.getImmediateExpansionRange(ExpansionStack.back()).first);
   SmallString<20> Buf;
   StringRef ArgName = Lexer::getSpelling(SourceMgr.getSpellingLoc(DefArgLoc),
  Buf, SourceMgr, LangOpts);
-  ArgUse = {nullptr, SourceLocation()};
+  ArgUse = MacroArgUse{nullptr, {}, SourceLocation()};
   if (!ArgName.empty())
-ArgUse = {&IdentTable.get(ArgName), SourceMgr.getSpellingLoc(DefArgLoc)};
+ArgUse = {&IdentTable.get(ArgName), std::move(ExpansionStack),
+  SourceMgr.getSpellingLoc(DefArgLoc)};
 }
 
 void EditedSource::startingCommit() {}
@@ -64,15 +69,18 @@
   }
 
   if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
-SourceLocation ExpLoc;
 MacroArgUse ArgUse;
-deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
+deconstructMacroArgLoc(OrigLoc, ArgUse);
+assert(!ArgUse.ExpansionStack.empty());
+SourceLocation ExpLoc = ArgUse.ExpansionStack.back();
 auto I = ExpansionToArgMap.find(ExpLoc.getRawEncoding());
 if (I != ExpansionToArgMap.end() &&
-std::find_if(
-I->second.begin(), I->second.end(), [&](const MacroArgUse &U) {
-  return ArgUse.first == U.first && ArgUse.second != U.second;
-}) != I->second.end()) {
+std::find_if(I->second.begin(), I->second.end(),
+ [&](const MacroArgUse &U) {
+   return ArgUse.Identifier == U.Identifier &&
+  std::tie(ArgUse.ExpansionStack, ArgUse.Use) !=
+  std::tie(U.ExpansionStack, U.Use);
+ }) != I->second.end()) {
   // Trying to write in a macro argument input that has already been
   // written by a previous commit for another expansion of the same macro
   // argument name. For example:
@@ -89,7 +97,6 @@
   return false;
 }
   }
-
   return true;
 }
 
@@ -102,13 +109,14 @@
 return true;
 
   if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
-SourceLocation ExpLoc;
 MacroArgUse ArgUse;
-deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
-if (ArgUse.first)
-  CurrCommitMacroArgExps.emplace_back(ExpLoc, ArgUse);
+deconstructMacroArgLoc(OrigLoc, ArgUse);
+if (ArgUse.Identifier) {
+  assert(!ArgUse.ExpansionStack.empty());
+  CurrCommitMacroArgExps.emplace_back(ArgUse.ExpansionStack.back(), ArgUse);
+}
   }
-  
+
   FileEdit &FA = FileEdits[Offs];
   if (FA.Text.empty()) {
 FA.Text = copyString(text);
Index: include/clang/Edit/EditedSource.h
===
--- include/clang/Edit/EditedSource.h
+++ include/clang/Edit/EditedSource.h
@@ -17,6 +17,

[PATCH] D34268: [clang] Fix format specifiers fixits for nested macros

2017-06-15 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 102781.
alexshap added a comment.

minor update


Repository:
  rL LLVM

https://reviews.llvm.org/D34268

Files:
  include/clang/Edit/EditedSource.h
  lib/Edit/EditedSource.cpp
  test/FixIt/fixit-format-darwin.m

Index: test/FixIt/fixit-format-darwin.m
===
--- test/FixIt/fixit-format-darwin.m
+++ test/FixIt/fixit-format-darwin.m
@@ -57,3 +57,20 @@
   Log3("test 7: %s", getNSInteger(), getNSUInteger());
   // CHECK: Log3("test 7: %ld", (long)getNSInteger(), (unsigned long)getNSUInteger());
 }
+
+#define Outer1(...) \
+do { \
+  printf(__VA_ARGS__); \
+} while (0)
+
+#define Outer2(...) \
+do { \
+  Outer1(__VA_ARGS__); Outer1(__VA_ARGS__); \
+} while (0)
+
+void bug33447() {
+  Outer2("test 8: %s", getNSInteger());  
+  // CHECK: Outer2("test 8: %ld", (long)getNSInteger());
+  Outer2("test 9: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Outer2("test 9: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+}
Index: lib/Edit/EditedSource.cpp
===
--- lib/Edit/EditedSource.cpp
+++ lib/Edit/EditedSource.cpp
@@ -24,17 +24,22 @@
 }
 
 void EditedSource::deconstructMacroArgLoc(SourceLocation Loc,
-  SourceLocation &ExpansionLoc,
   MacroArgUse &ArgUse) {
   assert(SourceMgr.isMacroArgExpansion(Loc));
   SourceLocation DefArgLoc = SourceMgr.getImmediateExpansionRange(Loc).first;
-  ExpansionLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
+  SmallVector ExpansionStack;
+  ExpansionStack.push_back(
+  SourceMgr.getImmediateExpansionRange(DefArgLoc).first);
+  while (SourceMgr.isMacroBodyExpansion(ExpansionStack.back()))
+ExpansionStack.push_back(
+SourceMgr.getImmediateExpansionRange(ExpansionStack.back()).first);
   SmallString<20> Buf;
   StringRef ArgName = Lexer::getSpelling(SourceMgr.getSpellingLoc(DefArgLoc),
  Buf, SourceMgr, LangOpts);
-  ArgUse = {nullptr, SourceLocation()};
+  ArgUse = MacroArgUse{nullptr, {}, SourceLocation()};
   if (!ArgName.empty())
-ArgUse = {&IdentTable.get(ArgName), SourceMgr.getSpellingLoc(DefArgLoc)};
+ArgUse = {&IdentTable.get(ArgName), std::move(ExpansionStack),
+  SourceMgr.getSpellingLoc(DefArgLoc)};
 }
 
 void EditedSource::startingCommit() {}
@@ -64,15 +69,17 @@
   }
 
   if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
-SourceLocation ExpLoc;
 MacroArgUse ArgUse;
-deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
+deconstructMacroArgLoc(OrigLoc, ArgUse);
+assert(!ArgUse.ExpansionStack.empty());
+SourceLocation ExpLoc = ArgUse.ExpansionStack.back();
 auto I = ExpansionToArgMap.find(ExpLoc.getRawEncoding());
 if (I != ExpansionToArgMap.end() &&
-std::find_if(
-I->second.begin(), I->second.end(), [&](const MacroArgUse &U) {
-  return ArgUse.first == U.first && ArgUse.second != U.second;
-}) != I->second.end()) {
+find_if(I->second, [&](const MacroArgUse &U) {
+  return ArgUse.Identifier == U.Identifier &&
+ std::tie(ArgUse.ExpansionStack, ArgUse.Use) !=
+ std::tie(U.ExpansionStack, U.Use);
+}) != I->second.end()) {
   // Trying to write in a macro argument input that has already been
   // written by a previous commit for another expansion of the same macro
   // argument name. For example:
@@ -89,7 +96,6 @@
   return false;
 }
   }
-
   return true;
 }
 
@@ -102,13 +108,14 @@
 return true;
 
   if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
-SourceLocation ExpLoc;
 MacroArgUse ArgUse;
-deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
-if (ArgUse.first)
-  CurrCommitMacroArgExps.emplace_back(ExpLoc, ArgUse);
+deconstructMacroArgLoc(OrigLoc, ArgUse);
+if (ArgUse.Identifier) {
+  assert(!ArgUse.ExpansionStack.empty());
+  CurrCommitMacroArgExps.emplace_back(ArgUse.ExpansionStack.back(), ArgUse);
+}
   }
-  
+
   FileEdit &FA = FileEdits[Offs];
   if (FA.Text.empty()) {
 FA.Text = copyString(text);
Index: include/clang/Edit/EditedSource.h
===
--- include/clang/Edit/EditedSource.h
+++ include/clang/Edit/EditedSource.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Support/Allocator.h"
 #include 
+#include 
 
 namespace clang {
   class LangOptions;
@@ -41,10 +42,20 @@
   typedef std::map FileEditsTy;
   FileEditsTy FileEdits;
 
-  // Location of argument use inside the macro body 
-  typedef std::pair MacroArgUse;
-  llvm::DenseMap>
-ExpansionToArgMap;
+  struct MacroArgUse {
+IdentifierInfo *Identifier;
+// Stack of macro expansions at given point of source code
+SmallVector ExpansionStack;
+// Location of argument use inside the top-level 

[PATCH] D34268: [clang] Fix format specifiers fixits for nested macros

2017-06-17 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

Ping


Repository:
  rL LLVM

https://reviews.llvm.org/D34268



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


[PATCH] D34268: [clang] Fix format specifiers fixits for nested macros

2017-06-19 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 103090.
alexshap added a comment.

Address code review comments


Repository:
  rL LLVM

https://reviews.llvm.org/D34268

Files:
  include/clang/Edit/EditedSource.h
  lib/Edit/EditedSource.cpp
  test/FixIt/fixit-format-darwin.m

Index: test/FixIt/fixit-format-darwin.m
===
--- test/FixIt/fixit-format-darwin.m
+++ test/FixIt/fixit-format-darwin.m
@@ -57,3 +57,20 @@
   Log3("test 7: %s", getNSInteger(), getNSUInteger());
   // CHECK: Log3("test 7: %ld", (long)getNSInteger(), (unsigned long)getNSUInteger());
 }
+
+#define Outer1(...) \
+do { \
+  printf(__VA_ARGS__); \
+} while (0)
+
+#define Outer2(...) \
+do { \
+  Outer1(__VA_ARGS__); Outer1(__VA_ARGS__); \
+} while (0)
+
+void bug33447() {
+  Outer2("test 8: %s", getNSInteger());  
+  // CHECK: Outer2("test 8: %ld", (long)getNSInteger());
+  Outer2("test 9: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Outer2("test 9: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+}
Index: lib/Edit/EditedSource.cpp
===
--- lib/Edit/EditedSource.cpp
+++ lib/Edit/EditedSource.cpp
@@ -24,17 +24,22 @@
 }
 
 void EditedSource::deconstructMacroArgLoc(SourceLocation Loc,
-  SourceLocation &ExpansionLoc,
   MacroArgUse &ArgUse) {
   assert(SourceMgr.isMacroArgExpansion(Loc));
   SourceLocation DefArgLoc = SourceMgr.getImmediateExpansionRange(Loc).first;
-  ExpansionLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
+  SmallVector ExpansionStack;
+  ExpansionStack.push_back(
+  SourceMgr.getImmediateExpansionRange(DefArgLoc).first);
+  while (SourceMgr.isMacroBodyExpansion(ExpansionStack.back()))
+ExpansionStack.push_back(
+SourceMgr.getImmediateExpansionRange(ExpansionStack.back()).first);
   SmallString<20> Buf;
   StringRef ArgName = Lexer::getSpelling(SourceMgr.getSpellingLoc(DefArgLoc),
  Buf, SourceMgr, LangOpts);
-  ArgUse = {nullptr, SourceLocation()};
+  ArgUse = MacroArgUse{nullptr, {}, SourceLocation()};
   if (!ArgName.empty())
-ArgUse = {&IdentTable.get(ArgName), SourceMgr.getSpellingLoc(DefArgLoc)};
+ArgUse = {&IdentTable.get(ArgName), std::move(ExpansionStack),
+  SourceMgr.getSpellingLoc(DefArgLoc)};
 }
 
 void EditedSource::startingCommit() {}
@@ -64,15 +69,17 @@
   }
 
   if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
-SourceLocation ExpLoc;
 MacroArgUse ArgUse;
-deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
+deconstructMacroArgLoc(OrigLoc, ArgUse);
+assert(!ArgUse.ExpansionStack.empty());
+SourceLocation ExpLoc = ArgUse.ExpansionStack.back();
 auto I = ExpansionToArgMap.find(ExpLoc.getRawEncoding());
 if (I != ExpansionToArgMap.end() &&
-std::find_if(
-I->second.begin(), I->second.end(), [&](const MacroArgUse &U) {
-  return ArgUse.first == U.first && ArgUse.second != U.second;
-}) != I->second.end()) {
+find_if(I->second, [&](const MacroArgUse &U) {
+  return ArgUse.Identifier == U.Identifier &&
+ std::tie(ArgUse.ExpansionStack.front(), ArgUse.UseLoc) !=
+ std::tie(U.ExpansionStack.front(), U.UseLoc);
+}) != I->second.end()) {
   // Trying to write in a macro argument input that has already been
   // written by a previous commit for another expansion of the same macro
   // argument name. For example:
@@ -89,7 +96,6 @@
   return false;
 }
   }
-
   return true;
 }
 
@@ -102,13 +108,14 @@
 return true;
 
   if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
-SourceLocation ExpLoc;
 MacroArgUse ArgUse;
-deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
-if (ArgUse.first)
-  CurrCommitMacroArgExps.emplace_back(ExpLoc, ArgUse);
+deconstructMacroArgLoc(OrigLoc, ArgUse);
+if (ArgUse.Identifier) {
+  assert(!ArgUse.ExpansionStack.empty());
+  CurrCommitMacroArgExps.emplace_back(ArgUse.ExpansionStack.back(), ArgUse);
+}
   }
-  
+
   FileEdit &FA = FileEdits[Offs];
   if (FA.Text.empty()) {
 FA.Text = copyString(text);
Index: include/clang/Edit/EditedSource.h
===
--- include/clang/Edit/EditedSource.h
+++ include/clang/Edit/EditedSource.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Support/Allocator.h"
 #include 
+#include 
 
 namespace clang {
   class LangOptions;
@@ -41,10 +42,20 @@
   typedef std::map FileEditsTy;
   FileEditsTy FileEdits;
 
-  // Location of argument use inside the macro body 
-  typedef std::pair MacroArgUse;
-  llvm::DenseMap>
-ExpansionToArgMap;
+  struct MacroArgUse {
+IdentifierInfo *Identifier;
+// Stack of macro expansions at given point of source code
+SmallVector ExpansionStack;
+// Location

[PATCH] D34268: [clang] Fix format specifiers fixits for nested macros

2017-06-19 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap marked 3 inline comments as done.
alexshap added inline comments.



Comment at: lib/Edit/EditedSource.cpp:80
+  return ArgUse.Identifier == U.Identifier &&
+ std::tie(ArgUse.ExpansionStack, ArgUse.Use) !=
+ std::tie(U.ExpansionStack, U.Use);

arphaman wrote:
> Do you need to compare the entire expansion stack, or can you get away with 
> just the comparison of the front of the stack?
yeah, you are right, we can compare only the fronts because the entire stack 
can be recovered from that (via calling  SourceMgr.getImmediateExpansionRange - 
like what's going on inside EditedSource::deconstructMacroArgLoc)


Repository:
  rL LLVM

https://reviews.llvm.org/D34268



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


[PATCH] D34268: [clang] Fix format specifiers fixits for nested macros

2017-06-19 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap planned changes to this revision.
alexshap marked an inline comment as done.
alexshap added a comment.

probably we don't need to keep the entire expansion stack in MacroArgUse (i was 
doing that because it was easier to understand what's going on).
I will update this diff soon.


Repository:
  rL LLVM

https://reviews.llvm.org/D34268



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


[PATCH] D34268: [clang] Fix format specifiers fixits for nested macros

2017-06-19 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 103093.
alexshap added a comment.

update, rerun the tests


Repository:
  rL LLVM

https://reviews.llvm.org/D34268

Files:
  include/clang/Edit/EditedSource.h
  lib/Edit/EditedSource.cpp
  test/FixIt/fixit-format-darwin.m

Index: test/FixIt/fixit-format-darwin.m
===
--- test/FixIt/fixit-format-darwin.m
+++ test/FixIt/fixit-format-darwin.m
@@ -57,3 +57,20 @@
   Log3("test 7: %s", getNSInteger(), getNSUInteger());
   // CHECK: Log3("test 7: %ld", (long)getNSInteger(), (unsigned long)getNSUInteger());
 }
+
+#define Outer1(...) \
+do { \
+  printf(__VA_ARGS__); \
+} while (0)
+
+#define Outer2(...) \
+do { \
+  Outer1(__VA_ARGS__); Outer1(__VA_ARGS__); \
+} while (0)
+
+void bug33447() {
+  Outer2("test 8: %s", getNSInteger());  
+  // CHECK: Outer2("test 8: %ld", (long)getNSInteger());
+  Outer2("test 9: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Outer2("test 9: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+}
Index: lib/Edit/EditedSource.cpp
===
--- lib/Edit/EditedSource.cpp
+++ lib/Edit/EditedSource.cpp
@@ -28,13 +28,18 @@
   MacroArgUse &ArgUse) {
   assert(SourceMgr.isMacroArgExpansion(Loc));
   SourceLocation DefArgLoc = SourceMgr.getImmediateExpansionRange(Loc).first;
-  ExpansionLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
+  SourceLocation ImmediateExpansionLoc =
+  SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
+  ExpansionLoc = ImmediateExpansionLoc;
+  while (SourceMgr.isMacroBodyExpansion(ExpansionLoc))
+ExpansionLoc = SourceMgr.getImmediateExpansionRange(ExpansionLoc).first;
   SmallString<20> Buf;
   StringRef ArgName = Lexer::getSpelling(SourceMgr.getSpellingLoc(DefArgLoc),
  Buf, SourceMgr, LangOpts);
-  ArgUse = {nullptr, SourceLocation()};
+  ArgUse = MacroArgUse{nullptr, SourceLocation(), SourceLocation()};
   if (!ArgName.empty())
-ArgUse = {&IdentTable.get(ArgName), SourceMgr.getSpellingLoc(DefArgLoc)};
+ArgUse = {&IdentTable.get(ArgName), ImmediateExpansionLoc,
+  SourceMgr.getSpellingLoc(DefArgLoc)};
 }
 
 void EditedSource::startingCommit() {}
@@ -69,10 +74,11 @@
 deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
 auto I = ExpansionToArgMap.find(ExpLoc.getRawEncoding());
 if (I != ExpansionToArgMap.end() &&
-std::find_if(
-I->second.begin(), I->second.end(), [&](const MacroArgUse &U) {
-  return ArgUse.first == U.first && ArgUse.second != U.second;
-}) != I->second.end()) {
+find_if(I->second, [&](const MacroArgUse &U) {
+  return ArgUse.Identifier == U.Identifier &&
+ std::tie(ArgUse.ImmediateExpansionLoc, ArgUse.UseLoc) !=
+ std::tie(U.ImmediateExpansionLoc, U.UseLoc);
+}) != I->second.end()) {
   // Trying to write in a macro argument input that has already been
   // written by a previous commit for another expansion of the same macro
   // argument name. For example:
@@ -89,7 +95,6 @@
   return false;
 }
   }
-
   return true;
 }
 
@@ -102,13 +107,13 @@
 return true;
 
   if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
-SourceLocation ExpLoc;
 MacroArgUse ArgUse;
+SourceLocation ExpLoc;
 deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
-if (ArgUse.first)
+if (ArgUse.Identifier)
   CurrCommitMacroArgExps.emplace_back(ExpLoc, ArgUse);
   }
-  
+
   FileEdit &FA = FileEdits[Offs];
   if (FA.Text.empty()) {
 FA.Text = copyString(text);
Index: include/clang/Edit/EditedSource.h
===
--- include/clang/Edit/EditedSource.h
+++ include/clang/Edit/EditedSource.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Support/Allocator.h"
 #include 
+#include 
 
 namespace clang {
   class LangOptions;
@@ -41,10 +42,20 @@
   typedef std::map FileEditsTy;
   FileEditsTy FileEdits;
 
-  // Location of argument use inside the macro body 
-  typedef std::pair MacroArgUse;
-  llvm::DenseMap>
-ExpansionToArgMap;
+  struct MacroArgUse {
+IdentifierInfo *Identifier;
+SourceLocation ImmediateExpansionLoc;
+// Location of argument use inside the top-level macro
+SourceLocation UseLoc;
+
+bool operator==(const MacroArgUse &Other) const {
+  return std::tie(Identifier, ImmediateExpansionLoc, UseLoc) ==
+ std::tie(Other.Identifier, Other.ImmediateExpansionLoc,
+  Other.UseLoc);
+}
+  };
+
+  llvm::DenseMap> ExpansionToArgMap;
   SmallVector, 2>
 CurrCommitMacroArgExps;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34268: [clang] Fix format specifiers fixits for nested macros

2017-06-20 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL305845: [clang] Fix format specifiers fixits for nested 
macros (authored by alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D34268?vs=103093&id=103262#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D34268

Files:
  cfe/trunk/include/clang/Edit/EditedSource.h
  cfe/trunk/lib/Edit/EditedSource.cpp
  cfe/trunk/test/FixIt/fixit-format-darwin.m

Index: cfe/trunk/include/clang/Edit/EditedSource.h
===
--- cfe/trunk/include/clang/Edit/EditedSource.h
+++ cfe/trunk/include/clang/Edit/EditedSource.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Support/Allocator.h"
 #include 
+#include 
 
 namespace clang {
   class LangOptions;
@@ -41,10 +42,20 @@
   typedef std::map FileEditsTy;
   FileEditsTy FileEdits;
 
-  // Location of argument use inside the macro body 
-  typedef std::pair MacroArgUse;
-  llvm::DenseMap>
-ExpansionToArgMap;
+  struct MacroArgUse {
+IdentifierInfo *Identifier;
+SourceLocation ImmediateExpansionLoc;
+// Location of argument use inside the top-level macro
+SourceLocation UseLoc;
+
+bool operator==(const MacroArgUse &Other) const {
+  return std::tie(Identifier, ImmediateExpansionLoc, UseLoc) ==
+ std::tie(Other.Identifier, Other.ImmediateExpansionLoc,
+  Other.UseLoc);
+}
+  };
+
+  llvm::DenseMap> ExpansionToArgMap;
   SmallVector, 2>
 CurrCommitMacroArgExps;
 
Index: cfe/trunk/test/FixIt/fixit-format-darwin.m
===
--- cfe/trunk/test/FixIt/fixit-format-darwin.m
+++ cfe/trunk/test/FixIt/fixit-format-darwin.m
@@ -57,3 +57,20 @@
   Log3("test 7: %s", getNSInteger(), getNSUInteger());
   // CHECK: Log3("test 7: %ld", (long)getNSInteger(), (unsigned long)getNSUInteger());
 }
+
+#define Outer1(...) \
+do { \
+  printf(__VA_ARGS__); \
+} while (0)
+
+#define Outer2(...) \
+do { \
+  Outer1(__VA_ARGS__); Outer1(__VA_ARGS__); \
+} while (0)
+
+void bug33447() {
+  Outer2("test 8: %s", getNSInteger());  
+  // CHECK: Outer2("test 8: %ld", (long)getNSInteger());
+  Outer2("test 9: %s %s", getNSInteger(), getNSInteger());
+  // CHECK: Outer2("test 9: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+}
Index: cfe/trunk/lib/Edit/EditedSource.cpp
===
--- cfe/trunk/lib/Edit/EditedSource.cpp
+++ cfe/trunk/lib/Edit/EditedSource.cpp
@@ -28,13 +28,18 @@
   MacroArgUse &ArgUse) {
   assert(SourceMgr.isMacroArgExpansion(Loc));
   SourceLocation DefArgLoc = SourceMgr.getImmediateExpansionRange(Loc).first;
-  ExpansionLoc = SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
+  SourceLocation ImmediateExpansionLoc =
+  SourceMgr.getImmediateExpansionRange(DefArgLoc).first;
+  ExpansionLoc = ImmediateExpansionLoc;
+  while (SourceMgr.isMacroBodyExpansion(ExpansionLoc))
+ExpansionLoc = SourceMgr.getImmediateExpansionRange(ExpansionLoc).first;
   SmallString<20> Buf;
   StringRef ArgName = Lexer::getSpelling(SourceMgr.getSpellingLoc(DefArgLoc),
  Buf, SourceMgr, LangOpts);
-  ArgUse = {nullptr, SourceLocation()};
+  ArgUse = MacroArgUse{nullptr, SourceLocation(), SourceLocation()};
   if (!ArgName.empty())
-ArgUse = {&IdentTable.get(ArgName), SourceMgr.getSpellingLoc(DefArgLoc)};
+ArgUse = {&IdentTable.get(ArgName), ImmediateExpansionLoc,
+  SourceMgr.getSpellingLoc(DefArgLoc)};
 }
 
 void EditedSource::startingCommit() {}
@@ -69,10 +74,11 @@
 deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
 auto I = ExpansionToArgMap.find(ExpLoc.getRawEncoding());
 if (I != ExpansionToArgMap.end() &&
-std::find_if(
-I->second.begin(), I->second.end(), [&](const MacroArgUse &U) {
-  return ArgUse.first == U.first && ArgUse.second != U.second;
-}) != I->second.end()) {
+find_if(I->second, [&](const MacroArgUse &U) {
+  return ArgUse.Identifier == U.Identifier &&
+ std::tie(ArgUse.ImmediateExpansionLoc, ArgUse.UseLoc) !=
+ std::tie(U.ImmediateExpansionLoc, U.UseLoc);
+}) != I->second.end()) {
   // Trying to write in a macro argument input that has already been
   // written by a previous commit for another expansion of the same macro
   // argument name. For example:
@@ -89,7 +95,6 @@
   return false;
 }
   }
-
   return true;
 }
 
@@ -102,13 +107,13 @@
 return true;
 
   if (SourceMgr.isMacroArgExpansion(OrigLoc)) {
-SourceLocation ExpLoc;
 MacroArgUse ArgUse;
+SourceLocation ExpLoc;
 deconstructMacroArgLoc(OrigLoc, ExpLoc, ArgUse);
-if (ArgUse.first)
+if (ArgUse.Identifier)
   CurrCommitMacroArgExps.emplace_back(ExpLoc, ArgUse);
   }
-  
+
   FileEdit &FA = FileE

[PATCH] D34496: [clang] Fix printf check for CFIndex

2017-06-22 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap planned changes to this revision.
alexshap added a comment.

ignore this diff for now, i will update it soon.


Repository:
  rL LLVM

https://reviews.llvm.org/D34496



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


[PATCH] D34496: [clang] Fix printf check for CFIndex

2017-06-22 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 103536.
alexshap added a comment.

update the tests


Repository:
  rL LLVM

https://reviews.llvm.org/D34496

Files:
  lib/Sema/SemaChecking.cpp
  test/FixIt/fixit-format-darwin.m
  test/FixIt/format-darwin.m

Index: test/FixIt/format-darwin.m
===
--- test/FixIt/format-darwin.m
+++ test/FixIt/format-darwin.m
@@ -7,13 +7,14 @@
 int printf(const char * restrict, ...);
 
 #if __LP64__
+typedef long CFIndex;
 typedef long NSInteger;
 typedef unsigned long NSUInteger;
 typedef int SInt32;
 typedef unsigned int UInt32;
 
 #else
-
+typedef int CFIndex;
 typedef int NSInteger;
 typedef unsigned int NSUInteger;
 typedef long SInt32;
@@ -27,6 +28,7 @@
   EnumValueB
 } NSIntegerEnum;
 
+CFIndex getCFIndex();
 NSInteger getNSInteger();
 NSUInteger getNSUInteger();
 SInt32 getSInt32();
@@ -55,6 +57,11 @@
 
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
+
+  printf("%s", getCFIndex()); // expected-warning{{values of type 'CFIndex' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
 }
 
 @interface Foo {
@@ -120,6 +127,11 @@
 
   // CHECK-64: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
   // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
+
+  printf("%d", getCFIndex()); // expected-warning{{values of type 'CFIndex' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK-64: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
+  // CHECK-64: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:16}:"(long)"
 }
 
 void testPreserveHex() {
@@ -167,6 +179,10 @@
   printf("%ld", getNSIntegerEnum()); // expected-warning{{enum values with underlying type 'NSInteger' should not be used as format arguments; add an explicit cast to 'long' instead}}
 
   // CHECK-32: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:"(long)"
+
+  printf("%ld", getCFIndex()); // expected-warning{{values of type 'CFIndex' should not be used as format arguments; add an explicit cast to 'long' instead}}
+
+  // CHECK-32: fix-it:"{{.*}}":{[[@LINE-2]]:17-[[@LINE-2]]:17}:"(long)"
 }
 
 void testPreserveHex() {
@@ -218,6 +234,11 @@
 
   // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
   // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:31}:"(long)"
+
+  printf("%s", (CFIndex)0); // expected-warning{{values of type 'CFIndex' should not be used as format arguments; add an explicit cast to 'long' instead}}
+  
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:13}:"%ld"
+  // CHECK: fix-it:"{{.*}}":{[[@LINE-3]]:16-[[@LINE-3]]:25}:"(long)"
 }
 
 void testCapitals() {
Index: test/FixIt/fixit-format-darwin.m
===
--- test/FixIt/fixit-format-darwin.m
+++ test/FixIt/fixit-format-darwin.m
@@ -8,12 +8,15 @@
 int printf(const char * restrict, ...);
 
 #if __LP64__
+typedef long CFIndex;
 typedef long NSInteger;
 typedef unsigned long NSUInteger;
 #else
+typedef int CFIndex;
 typedef int NSInteger;
 typedef unsigned int NSUInteger;
 #endif
+CFIndex getCFIndex();
 NSInteger getNSInteger();
 NSUInteger getNSUInteger();
 
@@ -74,3 +77,10 @@
   Outer2("test 9: %s %s", getNSInteger(), getNSInteger());
   // CHECK: Outer2("test 9: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
 }
+
+void testCFIndex() {
+  printf("test 10: %s", getCFIndex()); 
+  // CHECK: printf("test 10: %ld", (long)getCFIndex());
+  printf("test 11: %s %s", getCFIndex(), getCFIndex());
+  // CHECK: printf("test 11: %ld %ld", (long)getCFIndex(), (long)getCFIndex());
+}
Index: lib/Sema/SemaChecking.cpp
===
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -6000,6 +6000,7 @@
   while (const TypedefType *UserTy = TyTy->getAs()) {
 StringRef Name = UserTy->getDecl()->getName();
 QualType CastTy = llvm::StringSwitch(Name)
+  .Case("CFIndex", Context.LongTy)
   .Case("NSInteger", Context.LongTy)
   .Case("NSUInteger", Context.UnsignedLongTy)
   .Case("SInt32", Context.IntTy)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40809: [WIP] [analyzer] Dump counterexample traces as C programs

2017-12-13 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: lib/StaticAnalyzer/Core/BugReporterVisitors.cpp:1976
+unsigned FileEndOffset = SM.getFileOffset(SM.getLocForEndOfFile(FID));
+for (unsigned i=Offset; BufferStart[i] != '\n' && i < FileEndOffset; ++i)
+  Ostream << BufferStart[i];

spaces around '=' (maybe clang-format this diff ?)


https://reviews.llvm.org/D40809



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


[PATCH] D40809: [WIP] [analyzer] Dump counterexample traces as C programs

2017-12-15 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

Are there any plans to add tests for this ?


https://reviews.llvm.org/D40809



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


[PATCH] D43741: [Analyzer] More accurate modeling about the increment operator of the operand with type bool.

2018-03-01 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

i see, but just in case - what about the decrement operator ?


Repository:
  rC Clang

https://reviews.llvm.org/D43741



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


[PATCH] D52296: [Clang] - Add -gsingle-file-split-dwarf option.

2018-10-09 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

@grimar, this is an interesting observation which I've had on my mind for quite 
some time as well; a couple of things which I have not double-checked yet - 
just in case - do both gold and lld completely ignore dwo-related sections ? 
(did you check that ?), and another small question - just wondering if the 
debuggers (GDB and LLDB) are okay with it / or smth needs to be adjusted or 
fixed on their side. I guess everything should be fine, but asking just in case.


https://reviews.llvm.org/D52296



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


[PATCH] D52296: [Clang] - Add -gsingle-file-split-dwarf option.

2018-10-15 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

I see, many thanks. I've cherry-picked this patch locally and played with GDB - 
it appears to work fine with it. 
I'm also interested and support this change since this would simplify the 
adoption of Fission by some build systems.
@dblaikie, @echristo - are there any particular concerns with moving this 
forward ?


https://reviews.llvm.org/D52296



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


[PATCH] D52296: [Clang] - Add -gsingle-file-split-dwarf option.

2018-10-18 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

I talked to David @dblaikie offline about this diff yesterday, if I understood 
correctly this change is reasonable in general, @echristo  Eric, would you mind 
having a look at this diff ?


https://reviews.llvm.org/D52296



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


[PATCH] D52296: [Clang] - Add -gsingle-file-split-dwarf option.

2018-10-18 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

Ping


https://reviews.llvm.org/D52296



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


[PATCH] D53206: Allow padding checker to traverse simple class hierarchies

2018-10-29 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC345558: [analyzer] Allow padding checker to traverse simple 
class hierarchies (authored by alexshap, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D53206

Files:
  lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
  test/Analysis/padding_inherit.cpp

Index: test/Analysis/padding_inherit.cpp
===
--- test/Analysis/padding_inherit.cpp
+++ test/Analysis/padding_inherit.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_analyze_cc1 -std=c++14 -analyzer-checker=optin.performance -analyzer-config optin.performance.Padding:AllowedPad=20 -verify %s
+
+// A class that has no fields and one base class should visit that base class
+// instead. Note that despite having excess padding of 2, this is flagged
+// because of its usage in an array of 100 elements below (`ais').
+// TODO: Add a note to the bug report with BugReport::addNote() to mention the
+// variable using the class and also mention what class is inherting from what.
+// expected-warning@+1{{Excessive padding in 'struct FakeIntSandwich'}}
+struct FakeIntSandwich {
+  char c1;
+  int i;
+  char c2;
+};
+
+struct AnotherIntSandwich : FakeIntSandwich { // no-warning
+};
+
+// But we don't yet support multiple base classes.
+struct IntSandwich {};
+struct TooManyBaseClasses : FakeIntSandwich, IntSandwich { // no-warning
+};
+
+AnotherIntSandwich ais[100];
+
+struct Empty {};
+struct DoubleEmpty : Empty { // no-warning
+Empty e;
+};
Index: lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
+++ lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
@@ -75,6 +75,20 @@
 if (shouldSkipDecl(RD))
   return;
 
+// TODO: Figure out why we are going through declarations and not only
+// definitions.
+if (!(RD = RD->getDefinition()))
+  return;
+
+// This is the simplest correct case: a class with no fields and one base
+// class. Other cases are more complicated because of how the base classes
+// & fields might interact, so we don't bother dealing with them.
+// TODO: Support other combinations of base classes and fields.
+if (auto *CXXRD = dyn_cast(RD))
+  if (CXXRD->field_empty() && CXXRD->getNumBases() == 1)
+return visitRecord(CXXRD->bases().begin()->getType()->getAsRecordDecl(),
+   PadMultiplier);
+
 auto &ASTContext = RD->getASTContext();
 const ASTRecordLayout &RL = ASTContext.getASTRecordLayout(RD);
 assert(llvm::isPowerOf2_64(RL.getAlignment().getQuantity()));
@@ -112,12 +126,15 @@
 if (RT == nullptr)
   return;
 
-// TODO: Recurse into the fields and base classes to see if any
-// of those have excess padding.
+// TODO: Recurse into the fields to see if they have excess padding.
 visitRecord(RT->getDecl(), Elts);
   }
 
   bool shouldSkipDecl(const RecordDecl *RD) const {
+// TODO: Figure out why we are going through declarations and not only
+// definitions.
+if (!(RD = RD->getDefinition()))
+  return true;
 auto Location = RD->getLocation();
 // If the construct doesn't have a source file, then it's not something
 // we want to diagnose.
@@ -132,13 +149,14 @@
 // Not going to attempt to optimize unions.
 if (RD->isUnion())
   return true;
-// How do you reorder fields if you haven't got any?
-if (RD->field_empty())
-  return true;
 if (auto *CXXRD = dyn_cast(RD)) {
   // Tail padding with base classes ends up being very complicated.
-  // We will skip objects with base classes for now.
-  if (CXXRD->getNumBases() != 0)
+  // We will skip objects with base classes for now, unless they do not
+  // have fields.
+  // TODO: Handle more base class scenarios.
+  if (!CXXRD->field_empty() && CXXRD->getNumBases() != 0)
+return true;
+  if (CXXRD->field_empty() && CXXRD->getNumBases() != 1)
 return true;
   // Virtual bases are complicated, skipping those for now.
   if (CXXRD->getNumVBases() != 0)
@@ -150,6 +168,10 @@
   if (CXXRD->getTypeForDecl()->isInstantiationDependentType())
 return true;
 }
+// How do you reorder fields if you haven't got any?
+else if (RD->field_empty())
+  return true;
+
 auto IsTrickyField = [](const FieldDecl *FD) -> bool {
   // Bitfield layout is hard.
   if (FD->isBitField())
@@ -323,7 +345,7 @@
 BR->emitReport(std::move(Report));
   }
 };
-}
+} // namespace
 
 void ento::registerPaddingChecker(CheckerManager &Mgr) {
   Mgr.registerChecker();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37120: [analyzer] Fix modeling arithmetic

2017-08-25 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp:371-373
+return makeSymExprValNN(
+state, op, lhs.castAs(),
+rhs.castAs(), resultTy);

NoQ wrote:
> For now this code would return `UnknownVal` in most cases (pointer is not 
> tainted, or not symbolic, or contains an offset), and still construct an 
> invalid symbol in the rest of the cases (`makeSymExprValNN` would add the 
> number to the pointer symbol, instead of modelling an offset within the 
> pointed-to region).
> 
> Once D35450 finally lands (sorry for the delays...), it'd return `UnknownVal` 
> less often and crash more often.
@NoQ - many thanks for the code review!

i assume i might be missing smth, anyway, (replying to this comment and another 
one below)

  >This is probably the way to go: just take the Loc behind the LocAsInteger, 
cast it to char * (because 
  >pointer type shouldn't affect how much bytes of offset are added, anymore), 
add your integer to it, 
  >pack back into LocAsInteger

i'm not sure i understand how that would work here and somehow don't like it. 
For example, op can be MultiplicativeOp (i.e. long y = ((long)p) * 13;) 
extracting the Loc and doing smth with the Loc -  doesn't seem to be the right 
thing (if i understood your suggestion correctly)

  >For now this code would return UnknownVal in 
  >most cases (pointer is not tainted, or not symbolic, 
  >or contains an offset)

that was my understanding what this code should do (return UnknownVal in most 
cases unless we can reason about the actual (integer) values of LHS,RHS)




Repository:
  rL LLVM

https://reviews.llvm.org/D37120



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


[PATCH] D37120: [analyzer] Fix modeling arithmetic

2017-08-25 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp:363
 case nonloc::LocAsIntegerKind:
   return evalBinOpLL(state, op, lhsL,
  rhs.castAs().getLoc(),

@NoQ , @dcoughlin 
while we are looking at this code - just to double check - is this line (363) 
actually correct ?
Let's take a look at the following example:
   bool f(long x, double *p1, double *p2) {
  long y = (long)p1 - (long) p2; 
  // or,alternatively (long)p1 * (long)p2  or (long)p1 / (long)p2
  return y == x;
}
it looks like again the analyzer will try to use evalBinOpLL and evaluate this 
as an operation over pointers, while (if my understanding is correct) we should 
be working with integers here (and yes, in most cases it should return 
UnknownVal)
  


Repository:
  rL LLVM

https://reviews.llvm.org/D37120



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


[PATCH] D37120: [analyzer] Fix modeling arithmetic

2017-08-26 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 112784.
alexshap added a comment.

Return UnknownVal for non-comparison operations.
Add FIXME (improve modeling of "pointers as integers").


Repository:
  rL LLVM

https://reviews.llvm.org/D37120

Files:
  lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  test/Analysis/ptr-arith.cpp


Index: test/Analysis/ptr-arith.cpp
===
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -105,3 +105,9 @@
 return 0;
   return N;
 }
+
+// Bug 34309
+bool ptrAsIntegerSubtractionNoCrash(long x, char *p) {
+  long y = (long)p - 1;
+  return y == x;
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -360,10 +360,18 @@
   Loc lhsL = lhs.castAs().getLoc();
   switch (rhs.getSubKind()) {
 case nonloc::LocAsIntegerKind:
+  // FIXME: at the moment the implementation 
+  // of modeling "pointers as integers" is not complete.
+  if (!BinaryOperator::isComparisonOp(op))
+return UnknownVal(); 
   return evalBinOpLL(state, op, lhsL,
  rhs.castAs().getLoc(),
  resultTy);
 case nonloc::ConcreteIntKind: {
+  // FIXME: at the moment the implementation 
+  // of modeling "pointers as integers" is not complete.
+  if (!BinaryOperator::isComparisonOp(op))
+return UnknownVal();
   // Transform the integer into a location and compare.
   // FIXME: This only makes sense for comparisons. If we want to, say,
   // add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,


Index: test/Analysis/ptr-arith.cpp
===
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -105,3 +105,9 @@
 return 0;
   return N;
 }
+
+// Bug 34309
+bool ptrAsIntegerSubtractionNoCrash(long x, char *p) {
+  long y = (long)p - 1;
+  return y == x;
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -360,10 +360,18 @@
   Loc lhsL = lhs.castAs().getLoc();
   switch (rhs.getSubKind()) {
 case nonloc::LocAsIntegerKind:
+  // FIXME: at the moment the implementation 
+  // of modeling "pointers as integers" is not complete.
+  if (!BinaryOperator::isComparisonOp(op))
+return UnknownVal(); 
   return evalBinOpLL(state, op, lhsL,
  rhs.castAs().getLoc(),
  resultTy);
 case nonloc::ConcreteIntKind: {
+  // FIXME: at the moment the implementation 
+  // of modeling "pointers as integers" is not complete.
+  if (!BinaryOperator::isComparisonOp(op))
+return UnknownVal();
   // Transform the integer into a location and compare.
   // FIXME: This only makes sense for comparisons. If we want to, say,
   // add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D37120: [analyzer] Fix modeling arithmetic

2017-08-28 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

updated the patch per suggestion by @NoQ


Repository:
  rL LLVM

https://reviews.llvm.org/D37120



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


[PATCH] D37120: [analyzer] Fix modeling arithmetic

2017-08-28 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL311935: [analyzer] Fix crash in modeling arithmetic 
(authored by alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D37120?vs=112784&id=112967#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D37120

Files:
  cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  cfe/trunk/test/Analysis/ptr-arith.cpp


Index: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -360,10 +360,18 @@
   Loc lhsL = lhs.castAs().getLoc();
   switch (rhs.getSubKind()) {
 case nonloc::LocAsIntegerKind:
+  // FIXME: at the moment the implementation 
+  // of modeling "pointers as integers" is not complete.
+  if (!BinaryOperator::isComparisonOp(op))
+return UnknownVal(); 
   return evalBinOpLL(state, op, lhsL,
  rhs.castAs().getLoc(),
  resultTy);
 case nonloc::ConcreteIntKind: {
+  // FIXME: at the moment the implementation 
+  // of modeling "pointers as integers" is not complete.
+  if (!BinaryOperator::isComparisonOp(op))
+return UnknownVal();
   // Transform the integer into a location and compare.
   // FIXME: This only makes sense for comparisons. If we want to, say,
   // add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,
Index: cfe/trunk/test/Analysis/ptr-arith.cpp
===
--- cfe/trunk/test/Analysis/ptr-arith.cpp
+++ cfe/trunk/test/Analysis/ptr-arith.cpp
@@ -105,3 +105,9 @@
 return 0;
   return N;
 }
+
+// Bug 34309
+bool ptrAsIntegerSubtractionNoCrash(long x, char *p) {
+  long y = (long)p - 1;
+  return y == x;
+}


Index: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -360,10 +360,18 @@
   Loc lhsL = lhs.castAs().getLoc();
   switch (rhs.getSubKind()) {
 case nonloc::LocAsIntegerKind:
+  // FIXME: at the moment the implementation 
+  // of modeling "pointers as integers" is not complete.
+  if (!BinaryOperator::isComparisonOp(op))
+return UnknownVal(); 
   return evalBinOpLL(state, op, lhsL,
  rhs.castAs().getLoc(),
  resultTy);
 case nonloc::ConcreteIntKind: {
+  // FIXME: at the moment the implementation 
+  // of modeling "pointers as integers" is not complete.
+  if (!BinaryOperator::isComparisonOp(op))
+return UnknownVal();
   // Transform the integer into a location and compare.
   // FIXME: This only makes sense for comparisons. If we want to, say,
   // add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,
Index: cfe/trunk/test/Analysis/ptr-arith.cpp
===
--- cfe/trunk/test/Analysis/ptr-arith.cpp
+++ cfe/trunk/test/Analysis/ptr-arith.cpp
@@ -105,3 +105,9 @@
 return 0;
   return N;
 }
+
+// Bug 34309
+bool ptrAsIntegerSubtractionNoCrash(long x, char *p) {
+  long y = (long)p - 1;
+  return y == x;
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38151: [clang] Fix isExternC matcher docs

2017-09-21 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.
Herald added a subscriber: klimek.

The wording in the documentation for the matcher isExternC appears to be 
misleading since this
matcher is applicable to functions and variables as well. 
This diff changes the comment regenerates the html file.


Repository:
  rL LLVM

https://reviews.llvm.org/D38151

Files:
  docs/LibASTMatchersReference.html
  include/clang/ASTMatchers/ASTMatchers.h


Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3533,16 +3533,21 @@
   return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
 }
 
-/// \brief Matches extern "C" function declarations.
+/// \brief Matches extern "C" function or variable declarations.
 ///
 /// Given:
 /// \code
 ///   extern "C" void f() {}
 ///   extern "C" { void g() {} }
 ///   void h() {}
+///   extern "C" int x = 1;
+///   extern "C" int y = 2;
+///   int z = 3;
 /// \endcode
 /// functionDecl(isExternC())
-///   matches the declaration of f and g, but not the declaration h
+///   matches the declaration of f and g, but not the declaration of h.
+/// varDecl(isExternC())
+///   matches the declaration of x and y, but not the declaration of z.
 AST_POLYMORPHIC_MATCHER(isExternC, 
AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
VarDecl)) {
   return Node.isExternC();
Index: docs/LibASTMatchersReference.html
===
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -2741,19 +2741,22 @@
 Usable as: MatcherFunctionDecl>,
 MatcherVarDecl>,
 MatcherCXXRecordDecl>
 
 
-
 MatcherFunctionDecl>isExternC
-Matches extern "C" 
function declarations.
+Matches extern "C" 
function or variable declarations.
 
 Given:
   extern "C" void f() {}
   extern "C" { void g() {} }
   void h() {}
+  extern "C" int x = 1;
+  extern "C" int y = 2;
+  int z = 3;
 functionDecl(isExternC())
-  matches the declaration of f and g, but not the declaration h
+  matches the declaration of f and g, but not the declaration of h.
+varDecl(isExternC())
+  matches the declaration of x and y, but not the declaration of z.
 
 
-
 MatcherFunctionDecl>isInline
 Matches function and 
namespace declarations that are marked with
 the inline keyword.
@@ -3680,19 +3683,22 @@
 Usable as: MatcherFunctionDecl>,
 MatcherVarDecl>,
 MatcherCXXRecordDecl>
 
 
-
 MatcherVarDecl>isExternC
-Matches extern "C" 
function declarations.
+Matches extern "C" 
function or variable declarations.
 
 Given:
   extern "C" void f() {}
   extern "C" { void g() {} }
   void h() {}
+  extern "C" int x = 1;
+  extern "C" int y = 2;
+  int z = 3;
 functionDecl(isExternC())
-  matches the declaration of f and g, but not the declaration h
+  matches the declaration of f and g, but not the declaration of h.
+varDecl(isExternC())
+  matches the declaration of x and y, but not the declaration of z.
 
 
-
 MatcherVarDecl>isStaticStorageClass
 Matches 
variablefunction declarations that have "static" storage
 class specifier ("static" keyword) written in the source.


Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3533,16 +3533,21 @@
   return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
 }
 
-/// \brief Matches extern "C" function declarations.
+/// \brief Matches extern "C" function or variable declarations.
 ///
 /// Given:
 /// \code
 ///   extern "C" void f() {}
 ///   extern "C" { void g() {} }
 ///   void h() {}
+///   extern "C" int x = 1;
+///   extern "C" int y = 2;
+///   int z = 3;
 /// \endcode
 /// functionDecl(isExternC())
-///   matches the declaration of f and g, but not the declaration h
+///   matches the declaration of f and g, but not the declaration of h.
+/// varDecl(isExternC())
+///   matches the declaration of x and y, but not the declaration of z.
 AST_POLYMORPHIC_MATCHER(isExternC, AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
VarDecl)) {
   return Node.isExternC();
Index: docs/LibASTMatchersRe

[PATCH] D38159: [clang] Fix printf fixit for objc specific types

2017-09-21 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.

Let's take a look at the following example: 
for the triple thumbv7-apple-ios8.0.0 ssize_t is long and size_t is unsigned 
long,
while NSInteger is int and NSUinteger is unsigned int.
Following 
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html
Clang will catch it and insert a cast to long, for example
 printf("%zd", getNSInteger())
will be replaced with 
 printf("%zd", (long)getNSInteger())
but since the underlying type of ssize_t is long the specifier "%zd" is not 
getting replaced.
This diff changes this behavior to enabling replacing the specifier "%zd" with 
the correct one.

Test plan: make check-all


Repository:
  rL LLVM

https://reviews.llvm.org/D38159

Files:
  lib/Sema/SemaChecking.cpp
  test/FixIt/fixit-format-ios.m


Index: test/FixIt/fixit-format-ios.m
===
--- test/FixIt/fixit-format-ios.m
+++ test/FixIt/fixit-format-ios.m
@@ -0,0 +1,27 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -triple thumbv7-apple-ios8.0.0 -fsyntax-only -fblocks 
-Wformat -fixit %t
+// RUN: grep -v CHECK %t | FileCheck %s
+
+int printf(const char * restrict, ...);
+typedef unsigned int NSUInteger;
+typedef int NSInteger;
+NSUInteger getNSUInteger();
+NSInteger getNSInteger();
+
+void test() {
+  // For thumbv7-apple-ios8.0.0 
+  // the underlying type of size_t is unsigned long 
+  // and for ssize_t it is long.
+
+  printf("test 1: %zu", getNSUInteger()); 
+  // CHECK: printf("test 1: %lu", (unsigned long)getNSUInteger());
+
+  printf("test 2: %zu %zu", getNSUInteger(), getNSUInteger());
+  // CHECK: printf("test 2: %lu %lu", (unsigned long)getNSUInteger(), 
(unsigned long)getNSUInteger());
+
+  printf("test 3: %zd", getNSInteger()); 
+  // CHECK: printf("test 3: %ld", (long)getNSInteger());
+
+  printf("test 4: %zd %zd", getNSInteger(), getNSInteger());
+  // CHECK: printf("test 4: %ld %ld", (long)getNSInteger(), 
(long)getNSInteger());
+}
Index: lib/Sema/SemaChecking.cpp
===
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -6346,7 +6346,7 @@
   CastFix << ")";
 
   SmallVector Hints;
-  if (!AT.matchesType(S.Context, IntendedTy))
+  if (!AT.matchesType(S.Context, IntendedTy) || ShouldNotPrintDirectly) 
 Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str()));
 
   if (const CStyleCastExpr *CCast = dyn_cast(E)) {


Index: test/FixIt/fixit-format-ios.m
===
--- test/FixIt/fixit-format-ios.m
+++ test/FixIt/fixit-format-ios.m
@@ -0,0 +1,27 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -triple thumbv7-apple-ios8.0.0 -fsyntax-only -fblocks -Wformat -fixit %t
+// RUN: grep -v CHECK %t | FileCheck %s
+
+int printf(const char * restrict, ...);
+typedef unsigned int NSUInteger;
+typedef int NSInteger;
+NSUInteger getNSUInteger();
+NSInteger getNSInteger();
+
+void test() {
+  // For thumbv7-apple-ios8.0.0 
+  // the underlying type of size_t is unsigned long 
+  // and for ssize_t it is long.
+
+  printf("test 1: %zu", getNSUInteger()); 
+  // CHECK: printf("test 1: %lu", (unsigned long)getNSUInteger());
+
+  printf("test 2: %zu %zu", getNSUInteger(), getNSUInteger());
+  // CHECK: printf("test 2: %lu %lu", (unsigned long)getNSUInteger(), (unsigned long)getNSUInteger());
+
+  printf("test 3: %zd", getNSInteger()); 
+  // CHECK: printf("test 3: %ld", (long)getNSInteger());
+
+  printf("test 4: %zd %zd", getNSInteger(), getNSInteger());
+  // CHECK: printf("test 4: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+}
Index: lib/Sema/SemaChecking.cpp
===
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -6346,7 +6346,7 @@
   CastFix << ")";
 
   SmallVector Hints;
-  if (!AT.matchesType(S.Context, IntendedTy))
+  if (!AT.matchesType(S.Context, IntendedTy) || ShouldNotPrintDirectly) 
 Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str()));
 
   if (const CStyleCastExpr *CCast = dyn_cast(E)) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38159: [clang] Fix printf fixit for objc specific types

2017-09-22 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL314011: [clang] Fix printf fixit for objc specific types 
(authored by alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D38159?vs=116288&id=116380#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D38159

Files:
  cfe/trunk/lib/Sema/SemaChecking.cpp
  cfe/trunk/test/FixIt/fixit-format-ios.m


Index: cfe/trunk/lib/Sema/SemaChecking.cpp
===
--- cfe/trunk/lib/Sema/SemaChecking.cpp
+++ cfe/trunk/lib/Sema/SemaChecking.cpp
@@ -6346,7 +6346,7 @@
   CastFix << ")";
 
   SmallVector Hints;
-  if (!AT.matchesType(S.Context, IntendedTy))
+  if (!AT.matchesType(S.Context, IntendedTy) || ShouldNotPrintDirectly) 
 Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str()));
 
   if (const CStyleCastExpr *CCast = dyn_cast(E)) {
Index: cfe/trunk/test/FixIt/fixit-format-ios.m
===
--- cfe/trunk/test/FixIt/fixit-format-ios.m
+++ cfe/trunk/test/FixIt/fixit-format-ios.m
@@ -0,0 +1,26 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -triple thumbv7-apple-ios8.0.0 -fsyntax-only -Wformat 
-fixit %t
+// RUN: grep -v CHECK %t | FileCheck %s
+
+int printf(const char * restrict, ...);
+typedef unsigned int NSUInteger;
+typedef int NSInteger;
+NSUInteger getNSUInteger();
+NSInteger getNSInteger();
+
+void test() {
+  // For thumbv7-apple-ios8.0.0 the underlying type of ssize_t is long
+  // and the underlying type of size_t is unsigned long.
+
+  printf("test 1: %zu", getNSUInteger()); 
+  // CHECK: printf("test 1: %lu", (unsigned long)getNSUInteger());
+
+  printf("test 2: %zu %zu", getNSUInteger(), getNSUInteger());
+  // CHECK: printf("test 2: %lu %lu", (unsigned long)getNSUInteger(), 
(unsigned long)getNSUInteger());
+
+  printf("test 3: %zd", getNSInteger()); 
+  // CHECK: printf("test 3: %ld", (long)getNSInteger());
+
+  printf("test 4: %zd %zd", getNSInteger(), getNSInteger());
+  // CHECK: printf("test 4: %ld %ld", (long)getNSInteger(), 
(long)getNSInteger());
+}


Index: cfe/trunk/lib/Sema/SemaChecking.cpp
===
--- cfe/trunk/lib/Sema/SemaChecking.cpp
+++ cfe/trunk/lib/Sema/SemaChecking.cpp
@@ -6346,7 +6346,7 @@
   CastFix << ")";
 
   SmallVector Hints;
-  if (!AT.matchesType(S.Context, IntendedTy))
+  if (!AT.matchesType(S.Context, IntendedTy) || ShouldNotPrintDirectly) 
 Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str()));
 
   if (const CStyleCastExpr *CCast = dyn_cast(E)) {
Index: cfe/trunk/test/FixIt/fixit-format-ios.m
===
--- cfe/trunk/test/FixIt/fixit-format-ios.m
+++ cfe/trunk/test/FixIt/fixit-format-ios.m
@@ -0,0 +1,26 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -triple thumbv7-apple-ios8.0.0 -fsyntax-only -Wformat -fixit %t
+// RUN: grep -v CHECK %t | FileCheck %s
+
+int printf(const char * restrict, ...);
+typedef unsigned int NSUInteger;
+typedef int NSInteger;
+NSUInteger getNSUInteger();
+NSInteger getNSInteger();
+
+void test() {
+  // For thumbv7-apple-ios8.0.0 the underlying type of ssize_t is long
+  // and the underlying type of size_t is unsigned long.
+
+  printf("test 1: %zu", getNSUInteger()); 
+  // CHECK: printf("test 1: %lu", (unsigned long)getNSUInteger());
+
+  printf("test 2: %zu %zu", getNSUInteger(), getNSUInteger());
+  // CHECK: printf("test 2: %lu %lu", (unsigned long)getNSUInteger(), (unsigned long)getNSUInteger());
+
+  printf("test 3: %zd", getNSInteger()); 
+  // CHECK: printf("test 3: %ld", (long)getNSInteger());
+
+  printf("test 4: %zd %zd", getNSInteger(), getNSInteger());
+  // CHECK: printf("test 4: %ld %ld", (long)getNSInteger(), (long)getNSInteger());
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D38151: [clang] Fix isExternC matcher docs

2017-09-22 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL314022: [clang] Fix isExternC matcher docs (authored by 
alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D38151?vs=116251&id=116386#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D38151

Files:
  cfe/trunk/docs/LibASTMatchersReference.html
  cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h


Index: cfe/trunk/docs/LibASTMatchersReference.html
===
--- cfe/trunk/docs/LibASTMatchersReference.html
+++ cfe/trunk/docs/LibASTMatchersReference.html
@@ -2741,19 +2741,22 @@
 Usable as: MatcherFunctionDecl>,
 MatcherVarDecl>,
 MatcherCXXRecordDecl>
 
 
-
 MatcherFunctionDecl>isExternC
-Matches extern "C" 
function declarations.
+Matches extern "C" 
function or variable declarations.
 
 Given:
   extern "C" void f() {}
   extern "C" { void g() {} }
   void h() {}
+  extern "C" int x = 1;
+  extern "C" int y = 2;
+  int z = 3;
 functionDecl(isExternC())
-  matches the declaration of f and g, but not the declaration h
+  matches the declaration of f and g, but not the declaration of h.
+varDecl(isExternC())
+  matches the declaration of x and y, but not the declaration of z.
 
 
-
 MatcherFunctionDecl>isInline
 Matches function and 
namespace declarations that are marked with
 the inline keyword.
@@ -3680,19 +3683,22 @@
 Usable as: MatcherFunctionDecl>,
 MatcherVarDecl>,
 MatcherCXXRecordDecl>
 
 
-
 MatcherVarDecl>isExternC
-Matches extern "C" 
function declarations.
+Matches extern "C" 
function or variable declarations.
 
 Given:
   extern "C" void f() {}
   extern "C" { void g() {} }
   void h() {}
+  extern "C" int x = 1;
+  extern "C" int y = 2;
+  int z = 3;
 functionDecl(isExternC())
-  matches the declaration of f and g, but not the declaration h
+  matches the declaration of f and g, but not the declaration of h.
+varDecl(isExternC())
+  matches the declaration of x and y, but not the declaration of z.
 
 
-
 MatcherVarDecl>isStaticStorageClass
 Matches 
variablefunction declarations that have "static" storage
 class specifier ("static" keyword) written in the source.
Index: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
===
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
@@ -3533,16 +3533,21 @@
   return InnerMatcher.matches(Node.getReturnType(), Finder, Builder);
 }
 
-/// \brief Matches extern "C" function declarations.
+/// \brief Matches extern "C" function or variable declarations.
 ///
 /// Given:
 /// \code
 ///   extern "C" void f() {}
 ///   extern "C" { void g() {} }
 ///   void h() {}
+///   extern "C" int x = 1;
+///   extern "C" int y = 2;
+///   int z = 3;
 /// \endcode
 /// functionDecl(isExternC())
-///   matches the declaration of f and g, but not the declaration h
+///   matches the declaration of f and g, but not the declaration of h.
+/// varDecl(isExternC())
+///   matches the declaration of x and y, but not the declaration of z.
 AST_POLYMORPHIC_MATCHER(isExternC, 
AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl,
VarDecl)) {
   return Node.isExternC();


Index: cfe/trunk/docs/LibASTMatchersReference.html
===
--- cfe/trunk/docs/LibASTMatchersReference.html
+++ cfe/trunk/docs/LibASTMatchersReference.html
@@ -2741,19 +2741,22 @@
 Usable as: MatcherFunctionDecl>, MatcherVarDecl>, MatcherCXXRecordDecl>
 
 
-
 MatcherFunctionDecl>isExternC
-Matches extern "C" function declarations.
+Matches extern "C" function or variable declarations.
 
 Given:
   extern "C" void f() {}
   extern "C" { void g() {} }
   void h() {}
+  extern "C" int x = 1;
+  extern "C" int y = 2;
+  int z = 3;
 functionDecl(isExternC())
-  matches the declaration of f and g, but not the declaration h
+  matches the declaration of f and g, but not the declaration of h.
+varDecl(isExternC())
+  matches the declaration of x and y, 

[PATCH] D38214: [analyzer] Fix crash on modeling of pointer arithmetic

2017-09-25 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.
Herald added a subscriber: xazax.hun.

This patch attempts to fix analyzer's crash on the newly added test case (see 
also https://bugs.llvm.org/show_bug.cgi?id=34374).
Pointer subtraction appears to be modeled incorrectly in the following example:

  char* p;
  long n = p - reinterpret_cast((unsigned long)1);

In this case the analyzer (built without this patch) tries to create a symbolic 
value for the difference 
treating reinterpret_cast((unsigned long)1) as an integer, that is not 
correct.

Test plan: make check-all


Repository:
  rL LLVM

https://reviews.llvm.org/D38214

Files:
  lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  test/Analysis/ptr-arith.cpp


Index: test/Analysis/ptr-arith.cpp
===
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -111,3 +111,9 @@
   __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;
   return y == x;
 }
+
+// Bug 34374
+bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {
+  auto n = p - reinterpret_cast((__UINTPTR_TYPE__)1);
+  return n == m;
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -726,9 +726,11 @@
 if (Optional rInt = rhs.getAs()) {
   // If one of the operands is a symbol and the other is a constant,
   // build an expression for use by the constraint manager.
-  if (SymbolRef lSym = lhs.getAsLocSymbol(true))
-return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
-
+  if (SymbolRef lSym = lhs.getAsLocSymbol(true)) {
+if (BinaryOperator::isComparisonOp(op))
+  return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
+return UnknownVal();
+  }
   // Special case comparisons to NULL.
   // This must come after the test if the LHS is a symbol, which is used to
   // build constraints. The address of any non-symbolic region is 
guaranteed


Index: test/Analysis/ptr-arith.cpp
===
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -111,3 +111,9 @@
   __UINTPTR_TYPE__ y = (__UINTPTR_TYPE__)p - 1;
   return y == x;
 }
+
+// Bug 34374
+bool integerAsPtrSubtractionNoCrash(char *p, __UINTPTR_TYPE__ m) {
+  auto n = p - reinterpret_cast((__UINTPTR_TYPE__)1);
+  return n == m;
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -726,9 +726,11 @@
 if (Optional rInt = rhs.getAs()) {
   // If one of the operands is a symbol and the other is a constant,
   // build an expression for use by the constraint manager.
-  if (SymbolRef lSym = lhs.getAsLocSymbol(true))
-return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
-
+  if (SymbolRef lSym = lhs.getAsLocSymbol(true)) {
+if (BinaryOperator::isComparisonOp(op))
+  return MakeSymIntVal(lSym, op, rInt->getValue(), resultTy);
+return UnknownVal();
+  }
   // Special case comparisons to NULL.
   // This must come after the test if the LHS is a symbol, which is used to
   // build constraints. The address of any non-symbolic region is guaranteed
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D60974: Clang IFSO driver action.

2019-06-03 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: clang/lib/Frontend/InterfaceStubFunctionsConsumer.cpp:30
+uint8_t Binding;
+MangledSymbol() = delete;
+MangledSymbol(const std::string &Name, const std::string &ParentName,

would be nice to have a newline before the ctor


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D60974



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


[PATCH] D45897: Convert clang-interpreter to ORC JIT API

2018-04-20 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: examples/clang-interpreter/main.cpp:52
+class SimpleJIT {
+private:
+  ExecutionSession ES;

not needed



Comment at: examples/clang-interpreter/main.cpp:84
+
+  TargetMachine &getTargetMachine() { return *TM; }
 

const TargetMachine & ?



Comment at: examples/clang-interpreter/main.cpp:93
+
+  JITSymbol findSymbol(const std::string Name) {
+std::string MangledName;

const string & or maybe even StringRef  and the same below


Repository:
  rC Clang

https://reviews.llvm.org/D45897



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


[PATCH] D48845: [Sema] Add fixit for unused lambda captures

2018-07-05 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: lib/Sema/SemaLambda.cpp:1548
+  // Find the end of the explicit capture for use in fixits.
+  SourceLocation EndLoc;
+  if (From.isThisCapture() && From.isCopyCapture()) {

maybe these lines 1548 -1559 can be factored out into a helper function ?


Repository:
  rC Clang

https://reviews.llvm.org/D48845



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


[PATCH] D48845: [Sema] Add fixit for unused lambda captures

2018-07-05 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: lib/Sema/SemaLambda.cpp:1548
+  // Find the end of the explicit capture for use in fixits.
+  SourceLocation EndLoc;
+  if (From.isThisCapture() && From.isCopyCapture()) {

alexshap wrote:
> maybe these lines 1548 -1559 can be factored out into a helper function ?
+ maybe use a different name (EndLoc feels too generic in this particular 
case), but i don't insist


Repository:
  rC Clang

https://reviews.llvm.org/D48845



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


[PATCH] D48845: [Sema] Add fixit for unused lambda captures

2018-07-10 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

I'm kind of interested in this fixit, but one thought which i have - probably 
it should be more conservative (i.e. fix captures by reference, integral types, 
etc) (since the code might rely on side-effects of copy-ctors/move-ctors or 
extend the lifetime of an object), but fixing only simple cases still seems to 
be useful imo. CC: @aaron.ballman , @arphaman, @ahatanak


Repository:
  rC Clang

https://reviews.llvm.org/D48845



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


[PATCH] D48845: [Sema] Add fixit for unused lambda captures

2018-07-11 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

> Are you talking about a more conservative warning or a more conservative 
> fixit? If it doesn't make sense for us to have a fixit for a particular 
> capture, does it make sense for us to have a warning for that >capture in the 
> first place?

to be honest i'm more concerned with the fixit (so basically to avoid breaking 
the code - especially if these modifications are applied at scale, the code 
might be get broken silently and will be hard to find later, so I'd start with 
handling only simple cases where it's a strictly positive change)) )

> It would be helpful to add some tests with macros to ensure that the logic 
> for how the removal range is computed can handle macros. (E.g. macro that 
> expands to a full/partial capture, lambda in a macro).

+1


Repository:
  rC Clang

https://reviews.llvm.org/D48845



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


[PATCH] D48845: [Sema] Add fixit for unused lambda captures

2018-07-13 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap accepted this revision.
alexshap added a comment.
This revision is now accepted and ready to land.

to me LG


Repository:
  rC Clang

https://reviews.llvm.org/D48845



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


[PATCH] D48845: [Sema] Add fixit for unused lambda captures

2018-07-16 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC337148: [Sema] Add fixit for unused lambda captures 
(authored by alexshap, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D48845?vs=155616&id=155624#toc

Repository:
  rC Clang

https://reviews.llvm.org/D48845

Files:
  include/clang/Sema/DeclSpec.h
  include/clang/Sema/ScopeInfo.h
  include/clang/Sema/Sema.h
  lib/Parse/ParseExprCXX.cpp
  lib/Sema/SemaLambda.cpp
  test/FixIt/fixit-unused-lambda-capture.cpp

Index: lib/Sema/SemaLambda.cpp
===
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -993,6 +993,8 @@
   CheckCXXThisCapture(C->Loc, /*Explicit=*/true, /*BuildAndDiagnose*/ true,
   /*FunctionScopeIndexToStopAtPtr*/ nullptr,
   C->Kind == LCK_StarThis);
+  if (!LSI->Captures.empty())
+LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange;
   continue;
 }
 
@@ -1139,6 +1141,8 @@
TryCapture_ExplicitByVal;
   tryCaptureVariable(Var, C->Loc, Kind, EllipsisLoc);
 }
+if (!LSI->Captures.empty())
+  LSI->ExplicitCaptureRanges[LSI->Captures.size() - 1] = C->ExplicitRange;
   }
   finishLambdaExplicitCaptures(LSI);
 
@@ -1478,19 +1482,22 @@
   return false;
 }
 
-void Sema::DiagnoseUnusedLambdaCapture(const Capture &From) {
+bool Sema::DiagnoseUnusedLambdaCapture(SourceRange CaptureRange,
+   const Capture &From) {
   if (CaptureHasSideEffects(From))
-return;
+return false;
 
   if (From.isVLATypeCapture())
-return;
+return false;
 
   auto diag = Diag(From.getLocation(), diag::warn_unused_lambda_capture);
   if (From.isThisCapture())
 diag << "'this'";
   else
 diag << From.getVariable();
   diag << From.isNonODRUsed();
+  diag << FixItHint::CreateRemoval(CaptureRange);
+  return true;
 }
 
 ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
@@ -1532,18 +1539,49 @@
 
 // Translate captures.
 auto CurField = Class->field_begin();
+// True if the current capture has a used capture or default before it.
+bool CurHasPreviousCapture = CaptureDefault != LCD_None;
+SourceLocation PrevCaptureLoc = CurHasPreviousCapture ?
+CaptureDefaultLoc : IntroducerRange.getBegin();
+
 for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I, ++CurField) {
   const Capture &From = LSI->Captures[I];
+
   assert(!From.isBlockCapture() && "Cannot capture __block variables");
   bool IsImplicit = I >= LSI->NumExplicitCaptures;
 
+  // Use source ranges of explicit captures for fixits where available.
+  SourceRange CaptureRange = LSI->ExplicitCaptureRanges[I];
+
   // Warn about unused explicit captures.
+  bool IsCaptureUsed = true;
   if (!CurContext->isDependentContext() && !IsImplicit && !From.isODRUsed()) {
 // Initialized captures that are non-ODR used may not be eliminated.
 bool NonODRUsedInitCapture =
 IsGenericLambda && From.isNonODRUsed() && From.getInitExpr();
-if (!NonODRUsedInitCapture)
-  DiagnoseUnusedLambdaCapture(From);
+if (!NonODRUsedInitCapture) {
+  bool IsLast = (I + 1) == LSI->NumExplicitCaptures;
+	SourceRange FixItRange;
+  if (CaptureRange.isValid()) {
+if (!CurHasPreviousCapture && !IsLast) {
+  // If there are no captures preceding this capture, remove the
+  // following comma.
+  FixItRange = SourceRange(CaptureRange.getBegin(),
+   getLocForEndOfToken(CaptureRange.getEnd()));
+} else {
+  // Otherwise, remove the comma since the last used capture.
+  FixItRange = SourceRange(getLocForEndOfToken(PrevCaptureLoc),
+   CaptureRange.getEnd());
+}
+  }
+
+  IsCaptureUsed = !DiagnoseUnusedLambdaCapture(FixItRange, From);
+}
+  }
+
+  if (CaptureRange.isValid()) {
+CurHasPreviousCapture |= IsCaptureUsed;
+PrevCaptureLoc = CaptureRange.getEnd();
   }
 
   // Handle 'this' capture.
Index: lib/Parse/ParseExprCXX.cpp
===
--- lib/Parse/ParseExprCXX.cpp
+++ lib/Parse/ParseExprCXX.cpp
@@ -808,6 +808,7 @@
 IdentifierInfo *Id = nullptr;
 SourceLocation EllipsisLoc;
 ExprResult Init;
+SourceLocation LocStart = Tok.getLocation();
 
 if (Tok.is(tok::star)) {
   Loc = ConsumeToken(); 
@@ -981,8 +982,11 @@
   Loc, Kind == LCK_ByRef, Id, InitKind, InitExpr);
   Init = InitExpr;
 }
+
+SourceLocation LocEnd = PrevTokLocation;
+
 Intro.addCapture(Kind, Loc, Id, EllipsisLoc, InitKind, Init,
- InitCaptureType);
+   

[PATCH] D41042: [analyzer] StackAddrEscape: Delay turning on by default a little bit?

2017-12-08 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap accepted this revision.
alexshap added a comment.
This revision is now accepted and ready to land.

i see, to be honest, this is kind of unfortunate, if i am not mistaken, i've 
seen these false-positives, but not too many, most reports were real bugs. But 
if it's annoying, than i think it's fine to make it "alpha" until i figure out 
a good way to workaround this issue.


https://reviews.llvm.org/D41042



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


[PATCH] D132713: [clang-tidy] Skip union-like classes in use-equals-default

2022-08-29 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov added a comment.

ping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132713

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


[PATCH] D132713: [clang-tidy] Skip union-like classes in use-equals-default

2022-08-30 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov added inline comments.



Comment at: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp:220
 void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
-  // Skip unions since constructors with empty bodies behave differently
-  // in comparison with structs/classes.
+  // Skip union-like classes since constructors with empty bodies behave
+  // differently in comparison with structs/classes.

gribozavr2 wrote:
> 
I've come across "union-like" classes here: 
https://en.cppreference.com/w/cpp/language/union
but yeah, will rephrase the comment.



Comment at: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp:225
+  anyOf(isUnion(),
+has(fieldDecl(isImplicit(), hasType(cxxRecordDecl(isUnion()));
 

gribozavr2 wrote:
> Why is "isImplicit" needed?
the intention for this patch was to skip classes containing anonymous unions
https://en.cppreference.com/w/cpp/language/union
In this case Clang's AST looks like this:
CXXRecordDecl - /* union */ FieldDecl (implicit) - IndirectFieldDecl - 
IndirectFieldDecl ...
For regular unions I haven't encountered issues yet (on a few large codebases)
(but yeah, might have to revisit it in the future).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132713

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


[PATCH] D132713: [clang-tidy] Skip union-like classes in use-equals-default

2022-08-30 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov updated this revision to Diff 456800.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132713

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -42,6 +42,17 @@
   NE Field;
 };
 
+// Skip structs/classes containing anonymous unions.
+struct SU {
+  SU() {}
+  // CHECK-FIXES: SU() {}
+  ~SU() {}
+  // CHECK-FIXES: ~SU() {}
+  union {
+NE Field;
+  };
+};
+
 // Initializer or arguments.
 class IA {
 public:
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
@@ -44,6 +44,20 @@
   IL Field;
 };
 
+// Skip structs/classes containing anonymous unions.
+struct SU {
+  SU(const SU &Other) : Field(Other.Field) {}
+  // CHECK-FIXES: SU(const SU &Other) :
+  SU &operator=(const SU &Other) {
+Field = Other.Field;
+return *this;
+  }
+  // CHECK-FIXES: SU &operator=(const SU &Other) {
+  union {
+IL Field;
+  };
+};
+
 // Wrong type.
 struct WT {
   WT(const IL &Other) {}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -134,8 +134,8 @@
 
 - Improved `modernize-use-equals-default `_ check.
 
-  The check now skips unions since in this case a default constructor with empty body
-  is not equivalent to the explicitly defaulted one.
+  The check now skips unions/union-like classes since in this case a default constructor
+  with empty body is not equivalent to the explicitly defaulted one.
 
 Removed checks
 ^^
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -217,17 +217,20 @@
 }
 
 void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
-  // Skip unions since constructors with empty bodies behave differently
-  // in comparison with structs/classes.
+  // Skip unions/union-like classes since their constructors behave differently
+  // when defaulted vs. empty.
+  auto IsUnionLikeClass = recordDecl(
+  anyOf(isUnion(),
+has(fieldDecl(isImplicit(), hasType(cxxRecordDecl(isUnion()));
 
   // Destructor.
-  Finder->addMatcher(cxxDestructorDecl(unless(hasParent(recordDecl(isUnion(,
-   isDefinition())
- .bind(SpecialFunction),
- this);
+  Finder->addMatcher(
+  cxxDestructorDecl(unless(hasParent(IsUnionLikeClass)), isDefinition())
+  .bind(SpecialFunction),
+  this);
   Finder->addMatcher(
   cxxConstructorDecl(
-  unless(hasParent(recordDecl(isUnion(, isDefinition(),
+  unless(hasParent(IsUnionLikeClass)), isDefinition(),
   anyOf(
   // Default constructor.
   allOf(unless(hasAnyConstructorInitializer(isWritten())),
@@ -242,7 +245,7 @@
   this);
   // Copy-assignment operator.
   Finder->addMatcher(
-  cxxMethodDecl(unless(hasParent(recordDecl(isUnion(, isDefinition(),
+  cxxMethodDecl(unless(hasParent(IsUnionLikeClass)), isDefinition(),
 isCopyAssignmentOperator(),
 // isCopyAssignmentOperator() allows the parameter to be
 // passed by value, and in this case it cannot be
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D132998: [clang-tidy] Restrict use-equals-default to c++11-or-later

2022-08-31 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov created this revision.
alexander-shaposhnikov added reviewers: gribozavr2, njames93, aaron.ballman.
alexander-shaposhnikov created this object with visibility "All Users".
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a project: All.
alexander-shaposhnikov requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Restrict use-equals-default to c++11-or-later.

Test plan: ninja check-all


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132998

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx98.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx98.cpp
===
--- /dev/null
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx98.cpp
@@ -0,0 +1,8 @@
+// RUN: %check_clang_tidy -std=c++98 %s modernize-use-equals-default %t
+
+struct S {
+  S() {}
+  // CHECK-FIXES: S() {}
+  ~S() {}
+  // CHECK-FIXES: ~S() {}
+};
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -139,7 +139,7 @@
 - Improved `modernize-use-equals-default 
`_ check.
 
   The check now skips unions since in this case a default constructor with 
empty body
-  is not equivalent to the explicitly defaulted one.
+  is not equivalent to the explicitly defaulted one. The check is restricted 
to c++11-or-later.
 
 Removed checks
 ^^
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
@@ -38,7 +38,7 @@
 public:
   UseEqualsDefaultCheck(StringRef Name, ClangTidyContext *Context);
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
-return LangOpts.CPlusPlus;
+return LangOpts.CPlusPlus11;
   }
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx98.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx98.cpp
@@ -0,0 +1,8 @@
+// RUN: %check_clang_tidy -std=c++98 %s modernize-use-equals-default %t
+
+struct S {
+  S() {}
+  // CHECK-FIXES: S() {}
+  ~S() {}
+  // CHECK-FIXES: ~S() {}
+};
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -139,7 +139,7 @@
 - Improved `modernize-use-equals-default `_ check.
 
   The check now skips unions since in this case a default constructor with empty body
-  is not equivalent to the explicitly defaulted one.
+  is not equivalent to the explicitly defaulted one. The check is restricted to c++11-or-later.
 
 Removed checks
 ^^
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
@@ -38,7 +38,7 @@
 public:
   UseEqualsDefaultCheck(StringRef Name, ClangTidyContext *Context);
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
-return LangOpts.CPlusPlus;
+return LangOpts.CPlusPlus11;
   }
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D132998: [clang-tidy] Restrict use-equals-default to c++11-or-later

2022-08-31 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov added a comment.

My assumption was that a codebase needs to compile with c++11 in the first 
place - otherwise the automatic fixit will break the build (as it happens right 
now).
I was looking at modernize/UseOverrideCheck.h - it requires c++11 and this 
seemed to be quite natural.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132998

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


[PATCH] D133006: [clang-tidy] Skip copy assignment operators with nonstandard return types

2022-08-31 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov created this revision.
alexander-shaposhnikov added reviewers: njames93, gribozavr2, aaron.ballman.
alexander-shaposhnikov created this object with visibility "All Users".
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a project: All.
alexander-shaposhnikov requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Skip copy assignment operators with nonstandard return types since they cannot 
be defaulted.

Test plan: ninja check-clang-tools


Repository:
  rL LLVM

https://reviews.llvm.org/D133006

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
===
--- 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
@@ -444,6 +444,13 @@
   return *this;
 }
 
+// Wrong return type.
+struct WRTConstRef {
+  const WRTConstRef &operator = (const WRTConstRef &) {
+return *this;
+  }
+};
+
 // Try-catch.
 struct ITC {
   ITC(const ITC &Other)
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -139,7 +139,8 @@
 - Improved `modernize-use-equals-default 
`_ check.
 
   The check now skips unions since in this case a default constructor with 
empty body
-  is not equivalent to the explicitly defaulted one.
+  is not equivalent to the explicitly defaulted one. The check also skips
+  copy assignment operators with nonstandard return types.
 
 Removed checks
 ^^
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "UseEqualsDefaultCheck.h"
 #include "../utils/LexerUtils.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
@@ -247,7 +248,12 @@
 // isCopyAssignmentOperator() allows the parameter to be
 // passed by value, and in this case it cannot be
 // defaulted.
-hasParameter(0, hasType(lValueReferenceType(
+hasParameter(0, hasType(lValueReferenceType())),
+// isCopyAssignmentOperator() allows non lvalue reference
+// return types, and in this case it cannot be defaulted.
+returns(qualType(hasCanonicalType(
+allOf(lValueReferenceType(pointee(type())),
+  unless(matchers::isReferenceToConst()))
   .bind(SpecialFunction),
   this);
 }


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
@@ -444,6 +444,13 @@
   return *this;
 }
 
+// Wrong return type.
+struct WRTConstRef {
+  const WRTConstRef &operator = (const WRTConstRef &) {
+return *this;
+  }
+};
+
 // Try-catch.
 struct ITC {
   ITC(const ITC &Other)
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -139,7 +139,8 @@
 - Improved `modernize-use-equals-default `_ check.
 
   The check now skips unions since in this case a default constructor with empty body
-  is not equivalent to the explicitly defaulted one.
+  is not equivalent to the explicitly defaulted one. The check also skips
+  copy assignment operators with nonstandard return types.
 
 Removed checks
 ^^
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "UseEqualsDefaultCheck.h"
 #include "../utils/LexerUtils.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
@@ -247,7 +248,12 @@
 // isCopyAssignmentOperator() allows the parameter to be
 // p

[PATCH] D132998: [clang-tidy] Restrict use-equals-default to c++11-or-later

2022-08-31 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov added a comment.

Regarding the practical side - yeah, I've come across this issue (and others) 
while trying to run this check over a few large codebases (including LLVM and 
Chrome),
and this particular issue accounts of a few hundreds of build breakages.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132998

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


[PATCH] D133197: [clang] Fix crash when parsing scanf format string with missing arguments

2022-09-02 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov added a comment.

LG


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133197

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


[PATCH] D132998: [clang-tidy] Restrict use-equals-default to c++11-or-later

2022-09-02 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG47dbacbc8ae2: [clang-tidy] Restrict use-equals-default to 
c++11-or-later (authored by alexander-shaposhnikov).

Changed prior to commit:
  https://reviews.llvm.org/D132998?vs=456876&id=457715#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132998

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx98.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx98.cpp
===
--- /dev/null
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx98.cpp
@@ -0,0 +1,8 @@
+// RUN: %check_clang_tidy -std=c++98 %s modernize-use-equals-default %t
+
+struct S {
+  S() {}
+  // CHECK-FIXES: S() {}
+  ~S() {}
+  // CHECK-FIXES: ~S() {}
+};
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -145,7 +145,7 @@
   check.
 
   The check now skips unions since in this case a default constructor with 
empty body
-  is not equivalent to the explicitly defaulted one.
+  is not equivalent to the explicitly defaulted one. The check is restricted 
to c++11-or-later.
 
 Removed checks
 ^^
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
@@ -38,7 +38,7 @@
 public:
   UseEqualsDefaultCheck(StringRef Name, ClangTidyContext *Context);
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
-return LangOpts.CPlusPlus;
+return LangOpts.CPlusPlus11;
   }
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx98.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx98.cpp
@@ -0,0 +1,8 @@
+// RUN: %check_clang_tidy -std=c++98 %s modernize-use-equals-default %t
+
+struct S {
+  S() {}
+  // CHECK-FIXES: S() {}
+  ~S() {}
+  // CHECK-FIXES: ~S() {}
+};
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -145,7 +145,7 @@
   check.
 
   The check now skips unions since in this case a default constructor with empty body
-  is not equivalent to the explicitly defaulted one.
+  is not equivalent to the explicitly defaulted one. The check is restricted to c++11-or-later.
 
 Removed checks
 ^^
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.h
@@ -38,7 +38,7 @@
 public:
   UseEqualsDefaultCheck(StringRef Name, ClangTidyContext *Context);
   bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
-return LangOpts.CPlusPlus;
+return LangOpts.CPlusPlus11;
   }
   void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
   void registerMatchers(ast_matchers::MatchFinder *Finder) override;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133006: [clang-tidy] Skip copy assignment operators with nonstandard return types

2022-09-02 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGa7395b860bc2: [clang-tidy] Skip copy assignment operators 
with nonstandard return types (authored by alexander-shaposhnikov).

Changed prior to commit:
  https://reviews.llvm.org/D133006?vs=456902&id=457725#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133006

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
===
--- 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
@@ -444,6 +444,13 @@
   return *this;
 }
 
+// Wrong return type.
+struct WRTConstRef {
+  const WRTConstRef &operator = (const WRTConstRef &) {
+return *this;
+  }
+};
+
 // Try-catch.
 struct ITC {
   ITC(const ITC &Other)
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -145,7 +145,8 @@
   check.
 
   The check now skips unions since in this case a default constructor with 
empty body
-  is not equivalent to the explicitly defaulted one. The check is restricted 
to c++11-or-later.
+  is not equivalent to the explicitly defaulted one. The check also skips copy 
assignment
+  operators with nonstandard return types. The check is restricted to 
c++11-or-later.
 
 Removed checks
 ^^
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "UseEqualsDefaultCheck.h"
 #include "../utils/LexerUtils.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
@@ -247,7 +248,12 @@
 // isCopyAssignmentOperator() allows the parameter to be
 // passed by value, and in this case it cannot be
 // defaulted.
-hasParameter(0, hasType(lValueReferenceType(
+hasParameter(0, hasType(lValueReferenceType())),
+// isCopyAssignmentOperator() allows non lvalue reference
+// return types, and in this case it cannot be defaulted.
+returns(qualType(hasCanonicalType(
+allOf(lValueReferenceType(pointee(type())),
+  unless(matchers::isReferenceToConst()))
   .bind(SpecialFunction),
   this);
 }


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
@@ -444,6 +444,13 @@
   return *this;
 }
 
+// Wrong return type.
+struct WRTConstRef {
+  const WRTConstRef &operator = (const WRTConstRef &) {
+return *this;
+  }
+};
+
 // Try-catch.
 struct ITC {
   ITC(const ITC &Other)
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -145,7 +145,8 @@
   check.
 
   The check now skips unions since in this case a default constructor with empty body
-  is not equivalent to the explicitly defaulted one. The check is restricted to c++11-or-later.
+  is not equivalent to the explicitly defaulted one. The check also skips copy assignment
+  operators with nonstandard return types. The check is restricted to c++11-or-later.
 
 Removed checks
 ^^
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "UseEqualsDefaultCheck.h"
 #include "../utils/LexerUtils.h"
+#include "../utils/Matchers.h"
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
@@ -247,7 +248,12 @@
 // isCopyAssignmentOperator() allows the parameter to be
 // passed by value, and in this case it cannot be
 // d

[PATCH] D132713: [clang-tidy] Skip union-like classes in use-equals-default

2022-09-04 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov added a comment.

gentle ping


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132713

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


[PATCH] D132713: [clang-tidy] Skip union-like classes in use-equals-default

2022-09-06 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG44503482e0af: [clang-tidy] Skip union-like classes in 
use-equals-default (authored by alexander-shaposhnikov).

Changed prior to commit:
  https://reviews.llvm.org/D132713?vs=456800&id=458258#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D132713

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -42,6 +42,17 @@
   NE Field;
 };
 
+// Skip structs/classes containing anonymous unions.
+struct SU {
+  SU() {}
+  // CHECK-FIXES: SU() {}
+  ~SU() {}
+  // CHECK-FIXES: ~SU() {}
+  union {
+NE Field;
+  };
+};
+
 // Initializer or arguments.
 class IA {
 public:
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-copy.cpp
@@ -44,6 +44,20 @@
   IL Field;
 };
 
+// Skip structs/classes containing anonymous unions.
+struct SU {
+  SU(const SU &Other) : Field(Other.Field) {}
+  // CHECK-FIXES: SU(const SU &Other) :
+  SU &operator=(const SU &Other) {
+Field = Other.Field;
+return *this;
+  }
+  // CHECK-FIXES: SU &operator=(const SU &Other) {
+  union {
+IL Field;
+  };
+};
+
 // Wrong type.
 struct WT {
   WT(const IL &Other) {}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -144,9 +144,10 @@
 - Improved :doc:`modernize-use-equals-default `
   check.
 
-  The check now skips unions since in this case a default constructor with empty body
-  is not equivalent to the explicitly defaulted one. The check also skips copy assignment
-  operators with nonstandard return types. The check is restricted to c++11-or-later.
+  The check now skips unions/union-like classes since in this case a default constructor
+  with empty body is not equivalent to the explicitly defaulted one. The check also skips
+  copy assignment operators with nonstandard return types. The check is restricted to
+  c++11-or-later.
 
 Removed checks
 ^^
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -218,17 +218,20 @@
 }
 
 void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
-  // Skip unions since constructors with empty bodies behave differently
-  // in comparison with structs/classes.
+  // Skip unions/union-like classes since their constructors behave differently
+  // when defaulted vs. empty.
+  auto IsUnionLikeClass = recordDecl(
+  anyOf(isUnion(),
+has(fieldDecl(isImplicit(), hasType(cxxRecordDecl(isUnion()));
 
   // Destructor.
-  Finder->addMatcher(cxxDestructorDecl(unless(hasParent(recordDecl(isUnion(,
-   isDefinition())
- .bind(SpecialFunction),
- this);
+  Finder->addMatcher(
+  cxxDestructorDecl(unless(hasParent(IsUnionLikeClass)), isDefinition())
+  .bind(SpecialFunction),
+  this);
   Finder->addMatcher(
   cxxConstructorDecl(
-  unless(hasParent(recordDecl(isUnion(, isDefinition(),
+  unless(hasParent(IsUnionLikeClass)), isDefinition(),
   anyOf(
   // Default constructor.
   allOf(unless(hasAnyConstructorInitializer(isWritten())),
@@ -243,7 +246,7 @@
   this);
   // Copy-assignment operator.
   Finder->addMatcher(
-  cxxMethodDecl(unless(hasParent(recordDecl(isUnion(, isDefinition(),
+  cxxMethodDecl(unless(hasParent(IsUnionLikeClass)), isDefinition(),
 isCopyAssignmentOperator(),
 // isCopyAssignmentOperator() allows the parameter to be
 // passed by value, and in this case it cannot be
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D133741: [IR] Add alignment for llvm.threadlocal.address

2022-09-12 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov created this revision.
alexander-shaposhnikov added reviewers: ChuanqiXu, nikic, aeubanks.
alexander-shaposhnikov created this object with visibility "All Users".
Herald added a subscriber: hiraditya.
Herald added a project: All.
alexander-shaposhnikov requested review of this revision.
Herald added projects: clang, LLVM.
Herald added a subscriber: cfe-commits.

This diff sets the alignment attribute for the return value and the argument of 
llvm.threadlocal.address.

(https://github.com/llvm/llvm-project/issues/57438)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D133741

Files:
  clang/test/CodeGenCXX/cxx11-thread-local-instantiated.cpp
  clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp
  clang/test/CodeGenCXX/cxx11-thread-local.cpp
  clang/test/CodeGenCXX/cxx1y-variable-template.cpp
  clang/test/CodeGenCXX/cxx2a-thread-local-constinit.cpp
  clang/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
  clang/test/CodeGenCXX/pr18635.cpp
  clang/test/CodeGenCXX/threadlocal_address.cpp
  clang/test/Modules/initializers.cpp
  clang/test/OpenMP/parallel_copyin_codegen.cpp
  clang/test/OpenMP/parallel_copyin_combined_codegen.c
  clang/test/OpenMP/parallel_master_codegen.cpp
  clang/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp
  clang/test/OpenMP/threadprivate_codegen.cpp
  llvm/lib/IR/IRBuilder.cpp

Index: llvm/lib/IR/IRBuilder.cpp
===
--- llvm/lib/IR/IRBuilder.cpp
+++ llvm/lib/IR/IRBuilder.cpp
@@ -526,6 +526,14 @@
   return CreateCall(TheFn, Ops);
 }
 
+static MaybeAlign getAlign(Value *Ptr) {
+  if (auto *O = dyn_cast(Ptr))
+return O->getAlign();
+  if (auto *A = dyn_cast(Ptr))
+return A->getAliaseeObject()->getAlign();
+  return {};
+}
+
 CallInst *IRBuilderBase::CreateThreadLocalAddress(Value *Ptr) {
 #ifndef NDEBUG
   // Handle specially for constexpr cast. This is possible when
@@ -540,8 +548,13 @@
   assert(isa(V) && cast(V)->isThreadLocal() &&
  "threadlocal_address only applies to thread local variables.");
 #endif
-  return CreateIntrinsic(llvm::Intrinsic::threadlocal_address, {Ptr->getType()},
- {Ptr});
+  CallInst *CI = CreateIntrinsic(llvm::Intrinsic::threadlocal_address,
+ {Ptr->getType()}, {Ptr});
+  if (MaybeAlign A = getAlign(Ptr)) {
+CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), *A));
+CI->addRetAttr(Attribute::getWithAlignment(CI->getContext(), *A));
+  }
+  return CI;
 }
 
 CallInst *
Index: clang/test/OpenMP/threadprivate_codegen.cpp
===
--- clang/test/OpenMP/threadprivate_codegen.cpp
+++ clang/test/OpenMP/threadprivate_codegen.cpp
@@ -3662,7 +3662,7 @@
 // CHECK-TLS1-NEXT:[[A1:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], %struct.S3* [[TMP4]], i32 0, i32 0
 // CHECK-TLS1-NEXT:[[TMP5:%.*]] = load i32, i32* [[A1]], align 4
 // CHECK-TLS1-NEXT:store i32 [[TMP5]], i32* [[RES]], align 4
-// CHECK-TLS1-NEXT:[[TMP6:%.*]] = call %struct.Smain* @llvm.threadlocal.address.p0s_struct.Smains(%struct.Smain* @_ZZ4mainE2sm)
+// CHECK-TLS1-NEXT:[[TMP6:%.*]] = call align 8 %struct.Smain* @llvm.threadlocal.address.p0s_struct.Smains(%struct.Smain* align 8 @_ZZ4mainE2sm)
 // CHECK-TLS1-NEXT:[[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], %struct.Smain* [[TMP6]], i32 0, i32 0
 // CHECK-TLS1-NEXT:[[TMP7:%.*]] = load i32, i32* [[A2]], align 8
 // CHECK-TLS1-NEXT:[[TMP8:%.*]] = load i32, i32* [[RES]], align 4
@@ -3692,12 +3692,12 @@
 // CHECK-TLS1-NEXT:[[TMP19:%.*]] = load i32, i32* [[RES]], align 4
 // CHECK-TLS1-NEXT:[[ADD10:%.*]] = add nsw i32 [[TMP19]], [[TMP18]]
 // CHECK-TLS1-NEXT:store i32 [[ADD10]], i32* [[RES]], align 4
-// CHECK-TLS1-NEXT:[[TMP20:%.*]] = call i32* @llvm.threadlocal.address.p0i32(i32* @_ZN2STIiE2stE)
+// CHECK-TLS1-NEXT:[[TMP20:%.*]] = call align 4 i32* @llvm.threadlocal.address.p0i32(i32* align 4 @_ZN2STIiE2stE)
 // CHECK-TLS1-NEXT:[[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
 // CHECK-TLS1-NEXT:[[TMP22:%.*]] = load i32, i32* [[RES]], align 4
 // CHECK-TLS1-NEXT:[[ADD11:%.*]] = add nsw i32 [[TMP22]], [[TMP21]]
 // CHECK-TLS1-NEXT:store i32 [[ADD11]], i32* [[RES]], align 4
-// CHECK-TLS1-NEXT:[[TMP23:%.*]] = call float* @llvm.threadlocal.address.p0f32(float* @_ZN2STIfE2stE)
+// CHECK-TLS1-NEXT:[[TMP23:%.*]] = call align 4 float* @llvm.threadlocal.address.p0f32(float* align 4 @_ZN2STIfE2stE)
 // CHECK-TLS1-NEXT:[[TMP24:%.*]] = load float, float* [[TMP23]], align 4
 // CHECK-TLS1-NEXT:[[CONV:%.*]] = fptosi float [[TMP24]] to i32
 // CHECK-TLS1-NEXT:[[TMP25:%.*]] = load i32, i32* [[RES]], align 4
@@ -3716,7 +3716,7 @@
 // CHECK-TLS1-LABEL: define {{[^@]+}}@_ZTWL3gs1
 // CHECK-TLS1-SAME: () #[[ATTR5:[0-9]+]] {
 // CHECK-TLS1-NEXT:call void @_ZTHL3gs1()
-// CHECK-TLS1-NEXT:[[TMP1:%.*]] = call

[PATCH] D133741: [IR] Add alignment for llvm.threadlocal.address

2022-09-13 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb6965f7246bb: [IR] Add alignment for 
llvm.threadlocal.address (authored by alexander-shaposhnikov).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D133741

Files:
  clang/test/CodeGenCXX/cxx11-thread-local-instantiated.cpp
  clang/test/CodeGenCXX/cxx11-thread-local-reference.cpp
  clang/test/CodeGenCXX/cxx11-thread-local.cpp
  clang/test/CodeGenCXX/cxx1y-variable-template.cpp
  clang/test/CodeGenCXX/cxx2a-thread-local-constinit.cpp
  clang/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp
  clang/test/CodeGenCXX/pr18635.cpp
  clang/test/CodeGenCXX/threadlocal_address.cpp
  clang/test/Modules/initializers.cpp
  clang/test/OpenMP/parallel_copyin_codegen.cpp
  clang/test/OpenMP/parallel_copyin_combined_codegen.c
  clang/test/OpenMP/parallel_master_codegen.cpp
  clang/test/OpenMP/teams_distribute_parallel_for_copyin_codegen.cpp
  clang/test/OpenMP/threadprivate_codegen.cpp
  llvm/lib/IR/IRBuilder.cpp

Index: llvm/lib/IR/IRBuilder.cpp
===
--- llvm/lib/IR/IRBuilder.cpp
+++ llvm/lib/IR/IRBuilder.cpp
@@ -526,6 +526,14 @@
   return CreateCall(TheFn, Ops);
 }
 
+static MaybeAlign getAlign(Value *Ptr) {
+  if (auto *O = dyn_cast(Ptr))
+return O->getAlign();
+  if (auto *A = dyn_cast(Ptr))
+return A->getAliaseeObject()->getAlign();
+  return {};
+}
+
 CallInst *IRBuilderBase::CreateThreadLocalAddress(Value *Ptr) {
 #ifndef NDEBUG
   // Handle specially for constexpr cast. This is possible when
@@ -540,8 +548,13 @@
   assert(isa(V) && cast(V)->isThreadLocal() &&
  "threadlocal_address only applies to thread local variables.");
 #endif
-  return CreateIntrinsic(llvm::Intrinsic::threadlocal_address, {Ptr->getType()},
- {Ptr});
+  CallInst *CI = CreateIntrinsic(llvm::Intrinsic::threadlocal_address,
+ {Ptr->getType()}, {Ptr});
+  if (MaybeAlign A = getAlign(Ptr)) {
+CI->addParamAttr(0, Attribute::getWithAlignment(CI->getContext(), *A));
+CI->addRetAttr(Attribute::getWithAlignment(CI->getContext(), *A));
+  }
+  return CI;
 }
 
 CallInst *
Index: clang/test/OpenMP/threadprivate_codegen.cpp
===
--- clang/test/OpenMP/threadprivate_codegen.cpp
+++ clang/test/OpenMP/threadprivate_codegen.cpp
@@ -3662,7 +3662,7 @@
 // CHECK-TLS1-NEXT:[[A1:%.*]] = getelementptr inbounds [[STRUCT_S3:%.*]], %struct.S3* [[TMP4]], i32 0, i32 0
 // CHECK-TLS1-NEXT:[[TMP5:%.*]] = load i32, i32* [[A1]], align 4
 // CHECK-TLS1-NEXT:store i32 [[TMP5]], i32* [[RES]], align 4
-// CHECK-TLS1-NEXT:[[TMP6:%.*]] = call %struct.Smain* @llvm.threadlocal.address.p0s_struct.Smains(%struct.Smain* @_ZZ4mainE2sm)
+// CHECK-TLS1-NEXT:[[TMP6:%.*]] = call align 8 %struct.Smain* @llvm.threadlocal.address.p0s_struct.Smains(%struct.Smain* align 8 @_ZZ4mainE2sm)
 // CHECK-TLS1-NEXT:[[A2:%.*]] = getelementptr inbounds [[STRUCT_SMAIN:%.*]], %struct.Smain* [[TMP6]], i32 0, i32 0
 // CHECK-TLS1-NEXT:[[TMP7:%.*]] = load i32, i32* [[A2]], align 8
 // CHECK-TLS1-NEXT:[[TMP8:%.*]] = load i32, i32* [[RES]], align 4
@@ -3692,12 +3692,12 @@
 // CHECK-TLS1-NEXT:[[TMP19:%.*]] = load i32, i32* [[RES]], align 4
 // CHECK-TLS1-NEXT:[[ADD10:%.*]] = add nsw i32 [[TMP19]], [[TMP18]]
 // CHECK-TLS1-NEXT:store i32 [[ADD10]], i32* [[RES]], align 4
-// CHECK-TLS1-NEXT:[[TMP20:%.*]] = call i32* @llvm.threadlocal.address.p0i32(i32* @_ZN2STIiE2stE)
+// CHECK-TLS1-NEXT:[[TMP20:%.*]] = call align 4 i32* @llvm.threadlocal.address.p0i32(i32* align 4 @_ZN2STIiE2stE)
 // CHECK-TLS1-NEXT:[[TMP21:%.*]] = load i32, i32* [[TMP20]], align 4
 // CHECK-TLS1-NEXT:[[TMP22:%.*]] = load i32, i32* [[RES]], align 4
 // CHECK-TLS1-NEXT:[[ADD11:%.*]] = add nsw i32 [[TMP22]], [[TMP21]]
 // CHECK-TLS1-NEXT:store i32 [[ADD11]], i32* [[RES]], align 4
-// CHECK-TLS1-NEXT:[[TMP23:%.*]] = call float* @llvm.threadlocal.address.p0f32(float* @_ZN2STIfE2stE)
+// CHECK-TLS1-NEXT:[[TMP23:%.*]] = call align 4 float* @llvm.threadlocal.address.p0f32(float* align 4 @_ZN2STIfE2stE)
 // CHECK-TLS1-NEXT:[[TMP24:%.*]] = load float, float* [[TMP23]], align 4
 // CHECK-TLS1-NEXT:[[CONV:%.*]] = fptosi float [[TMP24]] to i32
 // CHECK-TLS1-NEXT:[[TMP25:%.*]] = load i32, i32* [[RES]], align 4
@@ -3716,7 +3716,7 @@
 // CHECK-TLS1-LABEL: define {{[^@]+}}@_ZTWL3gs1
 // CHECK-TLS1-SAME: () #[[ATTR5:[0-9]+]] {
 // CHECK-TLS1-NEXT:call void @_ZTHL3gs1()
-// CHECK-TLS1-NEXT:[[TMP1:%.*]] = call %struct.S1* @llvm.threadlocal.address.p0s_struct.S1s(%struct.S1* @_ZL3gs1)
+// CHECK-TLS1-NEXT:[[TMP1:%.*]] = call align 4 %struct.S1* @llvm.threadlocal.address.p0s_struct.S1s(%struct.S1* align 4 @_ZL3gs1)
 // CHECK-TLS1-NEXT:ret %struct.S1* [[TMP1]]
 //
 //
@@ -3750,7 +3750,7 @

[PATCH] D35972: Add warning to clang-reorder-fields when reordering breaks member init list dependencies

2017-07-29 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap accepted this revision.
alexshap added a comment.
This revision is now accepted and ready to land.

LGTM, thanks! 
do you have commit access ? (if not i can commit this patch for you)


https://reviews.llvm.org/D35972



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


[PATCH] D35972: Add warning to clang-reorder-fields when reordering breaks member init list dependencies

2017-07-29 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL309505: [clang-reorder-fields] Emit warning when reordering 
breaks member init list… (authored by alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D35972?vs=108812&id=108818#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D35972

Files:
  clang-tools-extra/trunk/clang-reorder-fields/ReorderFieldsAction.cpp
  clang-tools-extra/trunk/test/clang-reorder-fields/ClassDerived.cpp
  clang-tools-extra/trunk/test/clang-reorder-fields/FieldDependencyWarning.cpp
  
clang-tools-extra/trunk/test/clang-reorder-fields/FieldDependencyWarningDerived.cpp

Index: clang-tools-extra/trunk/test/clang-reorder-fields/FieldDependencyWarningDerived.cpp
===
--- clang-tools-extra/trunk/test/clang-reorder-fields/FieldDependencyWarningDerived.cpp
+++ clang-tools-extra/trunk/test/clang-reorder-fields/FieldDependencyWarningDerived.cpp
@@ -0,0 +1,36 @@
+// RUN: clang-reorder-fields -record-name bar::Derived -fields-order z,y %s -- 2>&1 | FileCheck --check-prefix=CHECK-MESSAGES %s
+// FIXME: clang-reorder-fields should provide -verify mode to make writing these checks
+// easier and more accurate, for now we follow clang-tidy's approach.
+
+namespace bar {
+struct Base {
+  int x;
+  int p;
+};
+
+class Derived : public Base {
+public:
+  Derived(long ny);
+  Derived(char nz);
+private:
+  long y;
+  char z;
+};
+
+Derived::Derived(long ny) : 
+  Base(),
+  y(ny), 
+  z(static_cast(y)) 
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: reordering field y after z makes y uninitialized when used in init expression
+{}
+
+Derived::Derived(char nz) : 
+  Base(),
+  y(nz),
+  // Check that base class fields are correctly ignored in reordering checks
+  // x has field index 1 and so would improperly warn if this wasn't the case since the command for this file swaps field indexes 1 and 2
+  z(x) 
+  // CHECK-MESSAGES-NOT: :[[@LINE-1]]:3: warning: reordering field x after z makes x uninitialized when used in init expression
+{}
+
+} // namespace bar
Index: clang-tools-extra/trunk/test/clang-reorder-fields/FieldDependencyWarning.cpp
===
--- clang-tools-extra/trunk/test/clang-reorder-fields/FieldDependencyWarning.cpp
+++ clang-tools-extra/trunk/test/clang-reorder-fields/FieldDependencyWarning.cpp
@@ -0,0 +1,54 @@
+// RUN: clang-reorder-fields -record-name bar::Foo -fields-order y,z,c,x %s -- 2>&1 | FileCheck --check-prefix=CHECK-MESSAGES %s
+// FIXME: clang-reorder-fields should provide -verify mode to make writing these checks
+// easier and more accurate, for now we follow clang-tidy's approach.
+
+namespace bar {
+
+struct Dummy {
+  Dummy(int x, char c) : x(x), c(c) {}
+  int x;
+  char c;
+};
+
+class Foo {
+public:
+  Foo(int x, double y, char cin);
+  Foo(int nx);
+  Foo();
+  int x;
+  double y;
+  char c;
+  Dummy z;
+};
+
+static char bar(char c) {
+  return c + 1;
+}
+
+Foo::Foo() : x(), y(), c(), z(0, 'a') {}
+
+Foo::Foo(int x, double y, char cin) :  
+  x(x), 
+  y(y), 
+  c(cin),   
+  z(this->x, bar(c))
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: reordering field x after z makes x uninitialized when used in init expression
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: reordering field c after z makes c uninitialized when used in init expression
+{}
+
+Foo::Foo(int nx) :
+  x(nx),  
+  y(x),
+  c(0),
+  z(bar(bar(x)), c) 
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: reordering field x after y makes x uninitialized when used in init expression
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: reordering field x after z makes x uninitialized when used in init expression
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: reordering field c after z makes c uninitialized when used in init expression
+{}
+
+} // namespace bar
+
+int main() {
+  bar::Foo F(5, 12.8, 'c');
+  return 0;
+}
Index: clang-tools-extra/trunk/test/clang-reorder-fields/ClassDerived.cpp
===
--- clang-tools-extra/trunk/test/clang-reorder-fields/ClassDerived.cpp
+++ clang-tools-extra/trunk/test/clang-reorder-fields/ClassDerived.cpp
@@ -0,0 +1,33 @@
+// RUN: clang-reorder-fields -record-name bar::Derived -fields-order z,y %s -- | FileCheck %s
+
+namespace bar {
+class Base {
+public:
+  Base(int nx, int np) : x(nx), p(np) {}
+  int x;
+  int p;
+};
+
+
+class Derived : public Base {
+public:
+  Derived(long ny);
+  Derived(char nz);
+private:
+  long y;
+  char z;
+};
+
+Derived::Derived(long ny) : 
+Base(ny, 0),
+y(ny),   // CHECK:   {{^  z\(static_cast\(ny\)\),}}
+z(static_cast(ny)) // CHECK-NEXT:  {{^  y\(ny\)}}
+{}
+
+Derived::Derived(char nz) : 
+Base(1, 2),
+y(nz),  // CHECK:   {{^  z\(x\),}}
+z(x)// CHECK-NEXT:  {{^  y\(nz\)}}
+{}
+
+} // names

[PATCH] D35972: Add warning to clang-reorder-fields when reordering breaks member init list dependencies

2017-07-29 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

https://reviews.llvm.org/rL309505 
plus I changed the code to emit this warning via DiagnosticEngine and updated 
the tests accordingly.


Repository:
  rL LLVM

https://reviews.llvm.org/D35972



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


[PATCH] D36564: [analyzer] Fix SimpleSValBuilder::simplifySVal

2017-08-09 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.
Herald added a subscriber: xazax.hun.

This diff attempts to address a crash (triggered assert) on the newly-added 
test case.
The assert being discussed is inside SValBuilder::evalBinOp

  if (Optional RV = rhs.getAs()) {
 // Support pointer arithmetic where the addend is on the left
 // and the pointer on the right.
 assert(op == BO_Add);

but the root cause seems to be in a different place (if I'm not missing smth).

The method simplifySVal appears to be doing the wrong thing for SVal "(char*)E 
- (char*)B".
Call stack: evalIntegralCast -> evalBinOpNN -> simplifySVal -> ... -> 
simplifySVal -> Simplifier::VisitSymSymExpr -> ...

Inside Simplifier::VisitSymSymExpr the call Visit(S->getLHS()) returns a NonLoc 
(where S->getLHS() represents char* E) while the call Visit(S->getRHS()) 
returns a Loc.

For Visit(S->getRHS()) this happens because in VisitSymbolData(const SymbolData 
*S) the "if" condition

  if (const llvm::APSInt *I =
 SVB.getKnownValue(State, nonloc::SymbolVal(S)))

is satisfied and Loc is correctly chosen.
For Visit(S->getLHS()) nonloc::SymbolVal(S) is used instead.
Next those values will passed to SValBuilder::evalBinOp and the code path

  if (Optional RV = rhs.getAs()) {
 // Support pointer arithmetic where the addend is on the left
 // and the pointer on the right.
assert(op == BO_Add);
 // Commute the operands.
return evalBinOpLN(state, op, *RV, lhs.castAs(), type);
  }

is executed instead of

  if (Optional LV = lhs.getAs()) {
if (Optional RV = rhs.getAs())
  return evalBinOpLL(state, op, *LV, *RV, type);
  
return evalBinOpLN(state, op, *LV, rhs.castAs(), type);
  }

Test plan: make check-all (green)


Repository:
  rL LLVM

https://reviews.llvm.org/D36564

Files:
  lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  test/Analysis/ptr-arith.cpp


Index: test/Analysis/ptr-arith.cpp
===
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -98,3 +98,10 @@
   int a[5][5];
*(*(a+1)+2) = 2;
 }
+
+unsigned ptrSubtractionNoCrash(char *Begin, char *End) {
+  auto N = End - Begin;
+  if (Begin)
+return 0;
+  return N;
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -1016,7 +1016,8 @@
   SVB.getKnownValue(State, nonloc::SymbolVal(S)))
 return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I)
 : (SVal)SVB.makeIntVal(*I);
-  return nonloc::SymbolVal(S);
+  return Loc::isLocType(S->getType()) ? (SVal)SVB.makeLoc(S) 
+  : nonloc::SymbolVal(S);
 }
 
 // TODO: Support SymbolCast. Support IntSymExpr when/if we actually


Index: test/Analysis/ptr-arith.cpp
===
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -98,3 +98,10 @@
   int a[5][5];
*(*(a+1)+2) = 2;
 }
+
+unsigned ptrSubtractionNoCrash(char *Begin, char *End) {
+  auto N = End - Begin;
+  if (Begin)
+return 0;
+  return N;
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -1016,7 +1016,8 @@
   SVB.getKnownValue(State, nonloc::SymbolVal(S)))
 return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I)
 : (SVal)SVB.makeIntVal(*I);
-  return nonloc::SymbolVal(S);
+  return Loc::isLocType(S->getType()) ? (SVal)SVB.makeLoc(S) 
+  : nonloc::SymbolVal(S);
 }
 
 // TODO: Support SymbolCast. Support IntSymExpr when/if we actually
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35109: [Analyzer] SValBuilder Comparison Rearrangement

2017-08-09 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp:561
+  // manager to handle these comparisons.
+  if (BinaryOperator::isComparisonOp(op) &&
+  rhs.getSubKind() == nonloc::SymbolValKind) {

some thoughts - evalBinOpNN is already pretty gigantic (300+ locs), 
imo it might be useful to reorganize the code (at least the newly added one) to 
improve readability.  
i.e. since a partial case (isSignedIntegerOrEnumerationType) is under 
consideration here,
probably it would be good (where it's reasonable) to move some details into a 
helper function/method.


https://reviews.llvm.org/D35109



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


[PATCH] D36564: [analyzer] Fix SimpleSValBuilder::simplifySVal

2017-08-14 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL310887: [analyzer] Fix SimpleSValBuilder::simplifySVal 
(authored by alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D36564?vs=110502&id=111073#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D36564

Files:
  cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  cfe/trunk/test/Analysis/ptr-arith.cpp


Index: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -1016,7 +1016,8 @@
   SVB.getKnownValue(State, nonloc::SymbolVal(S)))
 return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I)
 : (SVal)SVB.makeIntVal(*I);
-  return nonloc::SymbolVal(S);
+  return Loc::isLocType(S->getType()) ? (SVal)SVB.makeLoc(S) 
+  : nonloc::SymbolVal(S);
 }
 
 // TODO: Support SymbolCast. Support IntSymExpr when/if we actually
Index: cfe/trunk/test/Analysis/ptr-arith.cpp
===
--- cfe/trunk/test/Analysis/ptr-arith.cpp
+++ cfe/trunk/test/Analysis/ptr-arith.cpp
@@ -98,3 +98,10 @@
   int a[5][5];
*(*(a+1)+2) = 2;
 }
+
+unsigned ptrSubtractionNoCrash(char *Begin, char *End) {
+  auto N = End - Begin;
+  if (Begin)
+return 0;
+  return N;
+}


Index: cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -1016,7 +1016,8 @@
   SVB.getKnownValue(State, nonloc::SymbolVal(S)))
 return Loc::isLocType(S->getType()) ? (SVal)SVB.makeIntLocVal(*I)
 : (SVal)SVB.makeIntVal(*I);
-  return nonloc::SymbolVal(S);
+  return Loc::isLocType(S->getType()) ? (SVal)SVB.makeLoc(S) 
+  : nonloc::SymbolVal(S);
 }
 
 // TODO: Support SymbolCast. Support IntSymExpr when/if we actually
Index: cfe/trunk/test/Analysis/ptr-arith.cpp
===
--- cfe/trunk/test/Analysis/ptr-arith.cpp
+++ cfe/trunk/test/Analysis/ptr-arith.cpp
@@ -98,3 +98,10 @@
   int a[5][5];
*(*(a+1)+2) = 2;
 }
+
+unsigned ptrSubtractionNoCrash(char *Begin, char *End) {
+  auto N = End - Begin;
+  if (Begin)
+return 0;
+  return N;
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36715: [clang] minor cleanup in clang/tooling/refactoring

2017-08-14 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.

1. Add missing explicit.
2. Add missing std::move

(return type is Expected> but we return 
std::vector, so cast to && is necessary).

Test plan: make check-all


Repository:
  rL LLVM

https://reviews.llvm.org/D36715

Files:
  include/clang/Tooling/Refactoring/Rename/SymbolName.h
  lib/Tooling/Refactoring/Rename/RenamingAction.cpp


Index: lib/Tooling/Refactoring/Rename/RenamingAction.cpp
===
--- lib/Tooling/Refactoring/Rename/RenamingAction.cpp
+++ lib/Tooling/Refactoring/Rename/RenamingAction.cpp
@@ -53,7 +53,7 @@
 }
 Changes.push_back(std::move(Change));
   }
-  return Changes;
+  return std::move(Changes);
 }
 
 /// Takes each atomic change and inserts its replacements into the set of
Index: include/clang/Tooling/Refactoring/Rename/SymbolName.h
===
--- include/clang/Tooling/Refactoring/Rename/SymbolName.h
+++ include/clang/Tooling/Refactoring/Rename/SymbolName.h
@@ -29,7 +29,7 @@
 /// \endcode
 class SymbolName {
 public:
-  SymbolName(StringRef Name) {
+  explicit SymbolName(StringRef Name) {
 // While empty symbol names are valid (Objective-C selectors can have empty
 // name pieces), occurrences Objective-C selectors are created using an
 // array of strings instead of just one string.


Index: lib/Tooling/Refactoring/Rename/RenamingAction.cpp
===
--- lib/Tooling/Refactoring/Rename/RenamingAction.cpp
+++ lib/Tooling/Refactoring/Rename/RenamingAction.cpp
@@ -53,7 +53,7 @@
 }
 Changes.push_back(std::move(Change));
   }
-  return Changes;
+  return std::move(Changes);
 }
 
 /// Takes each atomic change and inserts its replacements into the set of
Index: include/clang/Tooling/Refactoring/Rename/SymbolName.h
===
--- include/clang/Tooling/Refactoring/Rename/SymbolName.h
+++ include/clang/Tooling/Refactoring/Rename/SymbolName.h
@@ -29,7 +29,7 @@
 /// \endcode
 class SymbolName {
 public:
-  SymbolName(StringRef Name) {
+  explicit SymbolName(StringRef Name) {
 // While empty symbol names are valid (Objective-C selectors can have empty
 // name pieces), occurrences Objective-C selectors are created using an
 // array of strings instead of just one string.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36715: [clang] minor cleanup in clang/tooling/refactoring

2017-08-15 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL310948: [clang] Code cleanup in clang/tooling (authored by 
alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D36715?vs=111078&id=111229#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D36715

Files:
  cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h
  cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp


Index: cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h
===
--- cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h
+++ cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h
@@ -29,7 +29,7 @@
 /// \endcode
 class SymbolName {
 public:
-  SymbolName(StringRef Name) {
+  explicit SymbolName(StringRef Name) {
 // While empty symbol names are valid (Objective-C selectors can have empty
 // name pieces), occurrences Objective-C selectors are created using an
 // array of strings instead of just one string.
Index: cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
===
--- cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
+++ cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
@@ -53,7 +53,7 @@
 }
 Changes.push_back(std::move(Change));
   }
-  return Changes;
+  return std::move(Changes);
 }
 
 /// Takes each atomic change and inserts its replacements into the set of


Index: cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h
===
--- cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h
+++ cfe/trunk/include/clang/Tooling/Refactoring/Rename/SymbolName.h
@@ -29,7 +29,7 @@
 /// \endcode
 class SymbolName {
 public:
-  SymbolName(StringRef Name) {
+  explicit SymbolName(StringRef Name) {
 // While empty symbol names are valid (Objective-C selectors can have empty
 // name pieces), occurrences Objective-C selectors are created using an
 // array of strings instead of just one string.
Index: cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
===
--- cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
+++ cfe/trunk/lib/Tooling/Refactoring/Rename/RenamingAction.cpp
@@ -53,7 +53,7 @@
 }
 Changes.push_back(std::move(Change));
   }
-  return Changes;
+  return std::move(Changes);
 }
 
 /// Takes each atomic change and inserts its replacements into the set of
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36851: [analyzer] Fix modeling of ctors

2017-08-17 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.
Herald added a subscriber: xazax.hun.

This diff attempts to fixe analyzer's crash (triggered assert) on the newly 
added test case.
The assert being discussed is assert(!B.lookup(R, BindingKey::Direct)) in 
lib/StaticAnalyzer/Core/RegionStore.cpp,
however the root cause appears to be different.
For classes with empty bases the offsets might be tricky.
For example, let's assume we have

  struct S: NonEmptyBase, EmptyBase {
 ...
  };

In this case Clang applies empty base class optimization and the offset of 
EmptyBase will be 0
(it can be verified via clang -cc1 -x c++ -v -fdump-record-layouts main.cpp 
-emit-llvm -o /dev/null).
When the analyzer tries to do zero initialization of EmptyBase it will hit the 
assert because that region has already been
"written" by the constructor of  NonEmptyBase.

Test plan:
make check-all


Repository:
  rL LLVM

https://reviews.llvm.org/D36851

Files:
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  test/Analysis/ctor.mm


Index: test/Analysis/ctor.mm
===
--- test/Analysis/ctor.mm
+++ test/Analysis/ctor.mm
@@ -704,3 +704,20 @@
 };
   }
 }
+
+namespace NoCrashOnEmptyBaseOptimization {
+  struct NonEmptyBase {
+int X;
+explicit NonEmptyBase(int X) : X(X) {}
+  };
+
+  struct EmptyBase {};
+
+  struct S : NonEmptyBase, EmptyBase {
+S() : NonEmptyBase(0), EmptyBase() {}
+  };
+
+  void testSCtorNoCrash() {
+S s;
+  }
+}
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -297,7 +297,17 @@
   ExplodedNodeSet PreInitialized;
   {
 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
-if (CE->requiresZeroInitialization()) {
+// FIXME: The offsets of empty bases can be tricky because of
+// of the so called "empty base class optimization".
+// If a base class has been optimized out
+// we should not try to create a binding, otherwise we should.
+// Unfortunately, at the moment ASTRecordLayout doesn't expose
+// the actual sizes of the empty bases
+// and trying to infer this from offsets/alignments
+// seems to be error-prone and tricky because of the trailing padding.
+// As a temporary mitigation we don't create a binding for empty bases.
+if (CE->requiresZeroInitialization() &&
+!CE->getConstructor()->getParent()->isEmpty()) {
   // Type of the zero doesn't matter.
   SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy);
 


Index: test/Analysis/ctor.mm
===
--- test/Analysis/ctor.mm
+++ test/Analysis/ctor.mm
@@ -704,3 +704,20 @@
 };
   }
 }
+
+namespace NoCrashOnEmptyBaseOptimization {
+  struct NonEmptyBase {
+int X;
+explicit NonEmptyBase(int X) : X(X) {}
+  };
+
+  struct EmptyBase {};
+
+  struct S : NonEmptyBase, EmptyBase {
+S() : NonEmptyBase(0), EmptyBase() {}
+  };
+
+  void testSCtorNoCrash() {
+S s;
+  }
+}
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -297,7 +297,17 @@
   ExplodedNodeSet PreInitialized;
   {
 StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
-if (CE->requiresZeroInitialization()) {
+// FIXME: The offsets of empty bases can be tricky because of
+// of the so called "empty base class optimization".
+// If a base class has been optimized out
+// we should not try to create a binding, otherwise we should.
+// Unfortunately, at the moment ASTRecordLayout doesn't expose
+// the actual sizes of the empty bases
+// and trying to infer this from offsets/alignments
+// seems to be error-prone and tricky because of the trailing padding.
+// As a temporary mitigation we don't create a binding for empty bases.
+if (CE->requiresZeroInitialization() &&
+!CE->getConstructor()->getParent()->isEmpty()) {
   // Type of the zero doesn't matter.
   SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy);
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36851: [analyzer] Fix modeling of ctors

2017-08-17 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.



  >One alternative we discussed was performing this logic in RegionStore 
instead and skipping the default binding there 
  >if we saw that the base region was empty. What do you think of that 
approach? (We would have to be careful for exactly the reasons described in 
your FIXME)

yeah, i thought about this option as well, i can update my diff to try that and 
see how it works.


Repository:
  rL LLVM

https://reviews.llvm.org/D36851



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


[PATCH] D36851: [analyzer] Fix modeling of ctors

2017-08-18 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap updated this revision to Diff 111622.
alexshap added a comment.

Skip the default binding for empty bases.


Repository:
  rL LLVM

https://reviews.llvm.org/D36851

Files:
  lib/StaticAnalyzer/Core/RegionStore.cpp
  test/Analysis/ctor.mm


Index: test/Analysis/ctor.mm
===
--- test/Analysis/ctor.mm
+++ test/Analysis/ctor.mm
@@ -704,3 +704,20 @@
 };
   }
 }
+
+namespace NoCrashOnEmptyBaseOptimization {
+  struct NonEmptyBase {
+int X;
+explicit NonEmptyBase(int X) : X(X) {}
+  };
+
+  struct EmptyBase {};
+
+  struct S : NonEmptyBase, EmptyBase {
+S() : NonEmptyBase(0), EmptyBase() {}
+  };
+
+  void testSCtorNoCrash() {
+S s;
+  }
+}
Index: lib/StaticAnalyzer/Core/RegionStore.cpp
===
--- lib/StaticAnalyzer/Core/RegionStore.cpp
+++ lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -409,6 +409,19 @@
 
   // BindDefault is only used to initialize a region with a default value.
   StoreRef BindDefault(Store store, const MemRegion *R, SVal V) override {
+// FIXME: The offsets of empty bases can be tricky because of
+// of the so called "empty base class optimization".
+// If a base class has been optimized out
+// we should not try to create a binding, otherwise we should.
+// Unfortunately, at the moment ASTRecordLayout doesn't expose
+// the actual sizes of the empty bases
+// and trying to infer them from offsets/alignments
+// seems to be error-prone and non-trivial because of the trailing padding.
+// As a temporary mitigation we don't create bindings for empty bases.
+if (R->getKind() == MemRegion::CXXBaseObjectRegionKind &&
+cast(R)->getDecl()->isEmpty())
+  return StoreRef(store, *this);
+
 RegionBindingsRef B = getRegionBindings(store);
 assert(!B.lookup(R, BindingKey::Direct));
 


Index: test/Analysis/ctor.mm
===
--- test/Analysis/ctor.mm
+++ test/Analysis/ctor.mm
@@ -704,3 +704,20 @@
 };
   }
 }
+
+namespace NoCrashOnEmptyBaseOptimization {
+  struct NonEmptyBase {
+int X;
+explicit NonEmptyBase(int X) : X(X) {}
+  };
+
+  struct EmptyBase {};
+
+  struct S : NonEmptyBase, EmptyBase {
+S() : NonEmptyBase(0), EmptyBase() {}
+  };
+
+  void testSCtorNoCrash() {
+S s;
+  }
+}
Index: lib/StaticAnalyzer/Core/RegionStore.cpp
===
--- lib/StaticAnalyzer/Core/RegionStore.cpp
+++ lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -409,6 +409,19 @@
 
   // BindDefault is only used to initialize a region with a default value.
   StoreRef BindDefault(Store store, const MemRegion *R, SVal V) override {
+// FIXME: The offsets of empty bases can be tricky because of
+// of the so called "empty base class optimization".
+// If a base class has been optimized out
+// we should not try to create a binding, otherwise we should.
+// Unfortunately, at the moment ASTRecordLayout doesn't expose
+// the actual sizes of the empty bases
+// and trying to infer them from offsets/alignments
+// seems to be error-prone and non-trivial because of the trailing padding.
+// As a temporary mitigation we don't create bindings for empty bases.
+if (R->getKind() == MemRegion::CXXBaseObjectRegionKind &&
+cast(R)->getDecl()->isEmpty())
+  return StoreRef(store, *this);
+
 RegionBindingsRef B = getRegionBindings(store);
 assert(!B.lookup(R, BindingKey::Direct));
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36075: [refactor] Initial support for refactoring action rules

2017-08-18 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added inline comments.



Comment at: include/clang/Basic/DiagnosticOr.h:40
+  /// diagnostic.
+  DiagnosticOr(PartialDiagnosticAt Diagnostic) : HasDiagnostic(true) {
+new (getDiagnosticStorage()) PartialDiagnosticAt(std::move(Diagnostic));

explicit ?



Comment at: include/clang/Basic/DiagnosticOr.h:49
+  OtherT &&Val,
+  typename std::enable_if::value>::type * =
+  nullptr)

 but probably it would be a bit cleaner to enable SFINAE via a template 
parameter (http://en.cppreference.com/w/cpp/types/enable_if , option #4) rather 
than via extra argument.



Comment at: include/clang/Tooling/Refactoring/RefactoringResult.h:27
+
+  RefactoringResult(AtomicChange Change) : Kind(AtomicChanges) {
+Changes.push_back(std::move(Change));

explicit ?


Repository:
  rL LLVM

https://reviews.llvm.org/D36075



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


[PATCH] D36851: [analyzer] Fix modeling of ctors

2017-08-18 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL311182: [analyzer] Fix modeling of constructors (authored by 
alexshap).

Changed prior to commit:
  https://reviews.llvm.org/D36851?vs=111622&id=111711#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D36851

Files:
  cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
  cfe/trunk/test/Analysis/ctor.mm


Index: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -409,6 +409,19 @@
 
   // BindDefault is only used to initialize a region with a default value.
   StoreRef BindDefault(Store store, const MemRegion *R, SVal V) override {
+// FIXME: The offsets of empty bases can be tricky because of
+// of the so called "empty base class optimization".
+// If a base class has been optimized out
+// we should not try to create a binding, otherwise we should.
+// Unfortunately, at the moment ASTRecordLayout doesn't expose
+// the actual sizes of the empty bases
+// and trying to infer them from offsets/alignments
+// seems to be error-prone and non-trivial because of the trailing padding.
+// As a temporary mitigation we don't create bindings for empty bases.
+if (R->getKind() == MemRegion::CXXBaseObjectRegionKind &&
+cast(R)->getDecl()->isEmpty())
+  return StoreRef(store, *this);
+
 RegionBindingsRef B = getRegionBindings(store);
 assert(!B.lookup(R, BindingKey::Direct));
 
Index: cfe/trunk/test/Analysis/ctor.mm
===
--- cfe/trunk/test/Analysis/ctor.mm
+++ cfe/trunk/test/Analysis/ctor.mm
@@ -704,3 +704,20 @@
 };
   }
 }
+
+namespace NoCrashOnEmptyBaseOptimization {
+  struct NonEmptyBase {
+int X;
+explicit NonEmptyBase(int X) : X(X) {}
+  };
+
+  struct EmptyBase {};
+
+  struct S : NonEmptyBase, EmptyBase {
+S() : NonEmptyBase(0), EmptyBase() {}
+  };
+
+  void testSCtorNoCrash() {
+S s;
+  }
+}


Index: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -409,6 +409,19 @@
 
   // BindDefault is only used to initialize a region with a default value.
   StoreRef BindDefault(Store store, const MemRegion *R, SVal V) override {
+// FIXME: The offsets of empty bases can be tricky because of
+// of the so called "empty base class optimization".
+// If a base class has been optimized out
+// we should not try to create a binding, otherwise we should.
+// Unfortunately, at the moment ASTRecordLayout doesn't expose
+// the actual sizes of the empty bases
+// and trying to infer them from offsets/alignments
+// seems to be error-prone and non-trivial because of the trailing padding.
+// As a temporary mitigation we don't create bindings for empty bases.
+if (R->getKind() == MemRegion::CXXBaseObjectRegionKind &&
+cast(R)->getDecl()->isEmpty())
+  return StoreRef(store, *this);
+
 RegionBindingsRef B = getRegionBindings(store);
 assert(!B.lookup(R, BindingKey::Direct));
 
Index: cfe/trunk/test/Analysis/ctor.mm
===
--- cfe/trunk/test/Analysis/ctor.mm
+++ cfe/trunk/test/Analysis/ctor.mm
@@ -704,3 +704,20 @@
 };
   }
 }
+
+namespace NoCrashOnEmptyBaseOptimization {
+  struct NonEmptyBase {
+int X;
+explicit NonEmptyBase(int X) : X(X) {}
+  };
+
+  struct EmptyBase {};
+
+  struct S : NonEmptyBase, EmptyBase {
+S() : NonEmptyBase(0), EmptyBase() {}
+  };
+
+  void testSCtorNoCrash() {
+S s;
+  }
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D36564: [analyzer] Fix SimpleSValBuilder::simplifySVal

2017-08-24 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

@alexfh, thanks for letting me know, i will take a closer look at 
https://bugs.llvm.org/show_bug.cgi?id=34309 soon.


Repository:
  rL LLVM

https://reviews.llvm.org/D36564



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


[PATCH] D36075: [refactor] Initial support for refactoring action rules

2017-08-24 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap added a comment.

@arphaman

  The selection requirement is supposed to be orthogonal to AST matchers, not a 
replacement. It should be used when working with source selection in editors. 
  I did mess around with moving over clang-reorder-fields using this kind of 
model and didn't see any issues when using AST matchers. Essentially I used the 
 requiredOption requirements and mapped them to run my 
  matching code instead of using the selection requirement. Thus this 
requirement was satisfied only when the AST matchers were successful. 
  It might be possible to simplify that pattern even further to make it simpler.

that's great, i'm interested in this too and would be happy to see 
clang-reorder-fields moving to clang-refactor (pls, let me know if i can help 
make this happen)


Repository:
  rL LLVM

https://reviews.llvm.org/D36075



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


[PATCH] D37120: [analyzer] Fix modeling arithmetic

2017-08-24 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexshap created this revision.
Herald added a subscriber: xazax.hun.

This diff attempts to fix modeling of arithmetic expressions
where pointers are treated as integers (i.e. via C-style / reinterpret casts).
In particular, it resolves https://bugs.llvm.org/show_bug.cgi?id=34309

Test plan: make check-all


Repository:
  rL LLVM

https://reviews.llvm.org/D37120

Files:
  lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
  test/Analysis/ptr-arith.cpp


Index: test/Analysis/ptr-arith.cpp
===
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -105,3 +105,9 @@
 return 0;
   return N;
 }
+
+// Bug 34309
+bool ptrAsIntegerSubtractionNoCrash(long x, char *p) {
+  long y = (long)p - 1;
+  return y == x;
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -364,6 +364,13 @@
  rhs.castAs().getLoc(),
  resultTy);
 case nonloc::ConcreteIntKind: {
+  // Evaluate pointers treated as integers
+  // (for example, results of C-style casts (long)((void *)ptr))
+  // in arithmetic expressions with integers.
+  if (!BinaryOperator::isComparisonOp(op))
+return makeSymExprValNN(
+state, op, lhs.castAs(),
+rhs.castAs(), resultTy);
   // Transform the integer into a location and compare.
   // FIXME: This only makes sense for comparisons. If we want to, say,
   // add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,


Index: test/Analysis/ptr-arith.cpp
===
--- test/Analysis/ptr-arith.cpp
+++ test/Analysis/ptr-arith.cpp
@@ -105,3 +105,9 @@
 return 0;
   return N;
 }
+
+// Bug 34309
+bool ptrAsIntegerSubtractionNoCrash(long x, char *p) {
+  long y = (long)p - 1;
+  return y == x;
+}
Index: lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
===
--- lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
+++ lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp
@@ -364,6 +364,13 @@
  rhs.castAs().getLoc(),
  resultTy);
 case nonloc::ConcreteIntKind: {
+  // Evaluate pointers treated as integers
+  // (for example, results of C-style casts (long)((void *)ptr))
+  // in arithmetic expressions with integers.
+  if (!BinaryOperator::isComparisonOp(op))
+return makeSymExprValNN(
+state, op, lhs.castAs(),
+rhs.castAs(), resultTy);
   // Transform the integer into a location and compare.
   // FIXME: This only makes sense for comparisons. If we want to, say,
   // add 1 to a LocAsInteger, we'd better unpack the Loc and add to it,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D136224: [clang-tidy] Skip private default ctors in modernize-use-equals-default

2022-10-18 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov created this revision.
alexander-shaposhnikov added reviewers: gribozavr2, alexfh, rsmith.
alexander-shaposhnikov created this object with visibility "All Users".
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a project: All.
alexander-shaposhnikov requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

For c++17 (i.e. before c++20) making  a private default ctor explicitly 
defaulted might expose the previously intentionally disallowed initializations,
e.g. class Tag { Tag() {} friend class Widget; }; is not equivalent to class 
Tag { Tag() = default; friend class Widget; }; since in the latter case Tag is 
treated as an aggregate despite having a declaration of the default 
constructor. This diff makes modernize-use-equals-default skip in-class empty 
nonpublic default ctors to avoid code breakages.

Test plan: ninja check-all


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D136224

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -90,14 +90,16 @@
 
 // Private constructor/destructor.
 class Priv {
-  Priv() {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: Priv() = default;
+  Priv();
   ~Priv() {};
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~Priv() = default;
 };
 
+Priv::Priv() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default'
+// CHECK-FIXES: Priv::Priv() = default;
+
 // struct.
 struct ST {
   ST() {}
Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
===
--- /dev/null
+++ 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-equals-default %t -- -- 
-fno-delayed-template-parsing -fexceptions
+
+// Private constructor/destructor.
+class Priv {
+  Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: Priv() = default;
+  ~Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~Priv() = default;
+};
+
+class PrivOutOfLine {
+  PrivOutOfLine();
+};
+
+PrivOutOfLine::PrivOutOfLine() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use '= default'
+// CHECK-FIXES: PrivOutOfLine::PrivOutOfLine() = default;
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,7 +158,8 @@
   The check now skips unions/union-like classes since in this case a default 
constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic 
constructors
   since they cannot be explicitly defaulted. The check also skips copy 
assignment operators
-  with nonstandard return types. The check is restricted to c++11-or-later.
+  with nonstandard return types, private/protected default constructors for 
c++17-or-earlier.
+  The check is restricted to c++11-or-later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
   ` to not
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -217,6 +217,10 @@
   Options.store(Opts, "IgnoreMacros", IgnoreMacros);
 }
 
+namespace {
+AST_MATCHER(CXXMethodDecl, isOutOfLine) { return Node.isOutOfLine(); }
+} // namespace
+
 void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
   // Skip unions/union-like classes since their constructors behave differently
   // when defaulted vs. empty.
@@ -224,6 +228,12 @@
   anyOf(isUnion(),
 has(fieldDecl(isImplicit(), hasType(cxxRecordDecl(isUnion()));
 
+  const LangOptions &LangOpts = getLangOpts();
+  auto IsPublicOrOutOfLineUntilCPP20 =
+  LangOpts.CPlusPlus20 || LangOpts.CPlusPlus2b
+  ? cxxConstructorDecl()
+  : cxxConstructorDecl(anyOf(isOutOfLine(), isPublic()));
+
   // Destructor.
   Finder->addMatcher(
   cxxDestructorDecl(unless(hasParent(IsUnionLikeClass)), isDefinition())
@@ -235,7 +245,8 @@
   anyOf(
   // Default constructor

[PATCH] D136224: [clang-tidy] Skip private default ctors in modernize-use-equals-default

2022-10-19 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov updated this revision to Diff 469063.
alexander-shaposhnikov added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136224

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -90,14 +90,16 @@
 
 // Private constructor/destructor.
 class Priv {
-  Priv() {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: Priv() = default;
+  Priv();
   ~Priv() {};
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~Priv() = default;
 };
 
+Priv::Priv() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default'
+// CHECK-FIXES: Priv::Priv() = default;
+
 // struct.
 struct ST {
   ST() {}
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
+
+// Private constructor/destructor.
+class Priv {
+  Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: Priv() = default;
+  ~Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~Priv() = default;
+};
+
+class PrivOutOfLine {
+  PrivOutOfLine();
+};
+
+PrivOutOfLine::PrivOutOfLine() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use '= default'
+// CHECK-FIXES: PrivOutOfLine::PrivOutOfLine() = default;
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy -std=c++17 %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
+
+// Private constructor/destructor.
+class Priv {
+  Priv() {}
+  ~Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~Priv() = default;
+};
+
+class PrivOutOfLine {
+  PrivOutOfLine();
+};
+
+PrivOutOfLine::PrivOutOfLine() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use '= default'
+// CHECK-FIXES: PrivOutOfLine::PrivOutOfLine() = default;
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,7 +158,8 @@
   The check now skips unions/union-like classes since in this case a default constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic constructors
   since they cannot be explicitly defaulted. The check also skips copy assignment operators
-  with nonstandard return types. The check is restricted to c++11-or-later.
+  with nonstandard return types, private/protected default constructors for c++17-or-earlier.
+  The check is restricted to c++11-or-later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
   ` to not
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -217,6 +217,10 @@
   Options.store(Opts, "IgnoreMacros", IgnoreMacros);
 }
 
+namespace {
+AST_MATCHER(CXXMethodDecl, isOutOfLine) { return Node.isOutOfLine(); }
+} // namespace
+
 void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
   // Skip unions/union-like classes since their constructors behave differently
   // when defaulted vs. empty.
@@ -224,6 +228,12 @@
   anyOf(isUnion(),
 has(fieldDecl(isImplicit(), hasType(cxxRecordDecl(isUnion()));
 
+  const LangOptions &LangOpts = getLangOpts();
+  auto IsPublicOrOutOfLineUntilCPP20 =
+  LangOpts.CPlusPlus20
+  ? cxxConstructorDecl()
+  : cxxConstructorDecl(anyOf(isOutOfLine(), isPublic()));
+
   // Destructor.
   Finder->addMatcher(
   cxxDestructorDecl(unless(hasParent(IsUnionLikeClass)), isDefinitio

[PATCH] D136224: [clang-tidy] Skip private default ctors in modernize-use-equals-default

2022-10-19 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov updated this revision to Diff 469086.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136224

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -90,14 +90,16 @@
 
 // Private constructor/destructor.
 class Priv {
-  Priv() {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: Priv() = default;
+  Priv();
   ~Priv() {};
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~Priv() = default;
 };
 
+Priv::Priv() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default'
+// CHECK-FIXES: Priv::Priv() = default;
+
 // struct.
 struct ST {
   ST() {}
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
+
+// Private constructor/destructor.
+class Priv {
+  Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: Priv() = default;
+  ~Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~Priv() = default;
+};
+
+class PrivOutOfLine {
+  PrivOutOfLine();
+};
+
+PrivOutOfLine::PrivOutOfLine() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use '= default'
+// CHECK-FIXES: PrivOutOfLine::PrivOutOfLine() = default;
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy -std=c++17 %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
+
+// Private constructor/destructor.
+class Priv {
+  Priv() {}
+  ~Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~Priv() = default;
+};
+
+class PrivOutOfLine {
+  PrivOutOfLine();
+};
+
+PrivOutOfLine::PrivOutOfLine() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use '= default'
+// CHECK-FIXES: PrivOutOfLine::PrivOutOfLine() = default;
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,7 +158,8 @@
   The check now skips unions/union-like classes since in this case a default constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic constructors
   since they cannot be explicitly defaulted. The check also skips copy assignment operators
-  with nonstandard return types. The check is restricted to c++11-or-later.
+  with nonstandard return types, private/protected default constructors for c++17 or earlier.
+  The check is restricted to c++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
   ` to not
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -217,6 +217,10 @@
   Options.store(Opts, "IgnoreMacros", IgnoreMacros);
 }
 
+namespace {
+AST_MATCHER(CXXMethodDecl, isOutOfLine) { return Node.isOutOfLine(); }
+} // namespace
+
 void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
   // Skip unions/union-like classes since their constructors behave differently
   // when defaulted vs. empty.
@@ -224,6 +228,12 @@
   anyOf(isUnion(),
 has(fieldDecl(isImplicit(), hasType(cxxRecordDecl(isUnion()));
 
+  const LangOptions &LangOpts = getLangOpts();
+  auto IsPublicOrOutOfLineUntilCPP20 =
+  LangOpts.CPlusPlus20
+  ? cxxConstructorDecl()
+  : cxxConstructorDecl(anyOf(isOutOfLine(), isPublic()));
+
   // Destructor.
   Finder->addMatcher(
   cxxDestructorDecl(unless(hasParent(IsUnionLikeClass)), isDefinition())
@@ -235,7 +245,8 @@
   anyOf(
   /

[PATCH] D136224: [clang-tidy] Skip private default ctors in modernize-use-equals-default

2022-10-19 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov updated this revision to Diff 469093.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136224

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -90,14 +90,16 @@
 
 // Private constructor/destructor.
 class Priv {
-  Priv() {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: Priv() = default;
+  Priv();
   ~Priv() {};
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~Priv() = default;
 };
 
+Priv::Priv() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default'
+// CHECK-FIXES: Priv::Priv() = default;
+
 // struct.
 struct ST {
   ST() {}
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
+
+// Private constructor/destructor.
+class Priv {
+  Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: Priv() = default;
+  ~Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~Priv() = default;
+};
+
+class PrivOutOfLine {
+  PrivOutOfLine();
+};
+
+PrivOutOfLine::PrivOutOfLine() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use '= default'
+// CHECK-FIXES: PrivOutOfLine::PrivOutOfLine() = default;
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy -std=c++17 %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
+
+// Private constructor/destructor.
+class Priv {
+  Priv() {}
+  ~Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~Priv() = default;
+};
+
+class PrivOutOfLine {
+  PrivOutOfLine();
+};
+
+PrivOutOfLine::PrivOutOfLine() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use '= default'
+// CHECK-FIXES: PrivOutOfLine::PrivOutOfLine() = default;
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,7 +158,8 @@
   The check now skips unions/union-like classes since in this case a default constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic constructors
   since they cannot be explicitly defaulted. The check also skips copy assignment operators
-  with nonstandard return types. The check is restricted to c++11-or-later.
+  with nonstandard return types, private/protected default constructors for C++17 or earlier.
+  The check is restricted to C++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
   ` to not
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -217,6 +217,10 @@
   Options.store(Opts, "IgnoreMacros", IgnoreMacros);
 }
 
+namespace {
+AST_MATCHER(CXXMethodDecl, isOutOfLine) { return Node.isOutOfLine(); }
+} // namespace
+
 void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
   // Skip unions/union-like classes since their constructors behave differently
   // when defaulted vs. empty.
@@ -224,6 +228,12 @@
   anyOf(isUnion(),
 has(fieldDecl(isImplicit(), hasType(cxxRecordDecl(isUnion()));
 
+  const LangOptions &LangOpts = getLangOpts();
+  auto IsPublicOrOutOfLineUntilCPP20 =
+  LangOpts.CPlusPlus20
+  ? cxxConstructorDecl()
+  : cxxConstructorDecl(anyOf(isOutOfLine(), isPublic()));
+
   // Destructor.
   Finder->addMatcher(
   cxxDestructorDecl(unless(hasParent(IsUnionLikeClass)), isDefinition())
@@ -235,7 +245,8 @@
   anyOf(
   /

[PATCH] D136224: [clang-tidy] Skip private default ctors in modernize-use-equals-default

2022-10-20 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG90d42b1cab04: [clang-tidy] Skip private default ctors in 
modernize-use-equals-default (authored by alexander-shaposhnikov).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136224

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
  
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -90,14 +90,16 @@
 
 // Private constructor/destructor.
 class Priv {
-  Priv() {}
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: Priv() = default;
+  Priv();
   ~Priv() {};
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~Priv() = default;
 };
 
+Priv::Priv() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default'
+// CHECK-FIXES: Priv::Priv() = default;
+
 // struct.
 struct ST {
   ST() {}
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx20.cpp
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy -std=c++20 %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
+
+// Private constructor/destructor.
+class Priv {
+  Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: Priv() = default;
+  ~Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~Priv() = default;
+};
+
+class PrivOutOfLine {
+  PrivOutOfLine();
+};
+
+PrivOutOfLine::PrivOutOfLine() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use '= default'
+// CHECK-FIXES: PrivOutOfLine::PrivOutOfLine() = default;
Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default-cxx17.cpp
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy -std=c++17 %s modernize-use-equals-default %t -- -- -fno-delayed-template-parsing -fexceptions
+
+// Private constructor/destructor.
+class Priv {
+  Priv() {}
+  ~Priv() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~Priv() = default;
+};
+
+class PrivOutOfLine {
+  PrivOutOfLine();
+};
+
+PrivOutOfLine::PrivOutOfLine() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use '= default'
+// CHECK-FIXES: PrivOutOfLine::PrivOutOfLine() = default;
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,7 +158,8 @@
   The check now skips unions/union-like classes since in this case a default constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic constructors
   since they cannot be explicitly defaulted. The check also skips copy assignment operators
-  with nonstandard return types. The check is restricted to c++11-or-later.
+  with nonstandard return types, private/protected default constructors for C++17 or earlier.
+  The check is restricted to C++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
   ` to not
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -217,6 +217,10 @@
   Options.store(Opts, "IgnoreMacros", IgnoreMacros);
 }
 
+namespace {
+AST_MATCHER(CXXMethodDecl, isOutOfLine) { return Node.isOutOfLine(); }
+} // namespace
+
 void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
   // Skip unions/union-like classes since their constructors behave differently
   // when defaulted vs. empty.
@@ -224,6 +228,12 @@
   anyOf(isUnion(),
 has(fieldDecl(isImplicit(), hasType(cxxRecordDecl(isUnion()));
 
+  const LangOptions &LangOpts = getLangOpts();
+  auto IsPublicOrOutOfLineUntilCPP20 =
+  LangOpts.CPlusPlus20
+  ? cxxConstructorDecl()
+  : cxxConstructorDecl(anyOf(isOutOfLine(), isPublic()));
+
   // Destructor

[PATCH] D136399: [clang-tidy][modernize-use-equals-default] Avoid adding unnecessary semicolon

2022-10-20 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov created this revision.
alexander-shaposhnikov added reviewers: gribozavr2, ymandel, alexfh, 
LegalizeAdulthood.
alexander-shaposhnikov created this object with visibility "All Users".
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a project: All.
alexander-shaposhnikov requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Adjust the automatic to avoid adding superfluous semicolon.

Test plan: ninja check-all


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D136399

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -91,7 +91,7 @@
 // Private constructor/destructor.
 class Priv {
   Priv();
-  ~Priv() {};
+  ~Priv() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~Priv() = default;
 };
@@ -100,14 +100,28 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default'
 // CHECK-FIXES: Priv::Priv() = default;
 
+struct SemiColon {
+  SemiColon() {};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: SemiColon() = default;{{$}}
+};
+
+struct SemiColonOutOfLine {
+  SemiColonOutOfLine();
+};
+
+SemiColonOutOfLine::SemiColonOutOfLine() {};
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use '= default'
+// CHECK-FIXES: SemiColonOutOfLine::SemiColonOutOfLine() = default;{{$}}
+
 // struct.
 struct ST {
   ST() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ST() = default;
+  // CHECK-FIXES: ST() = default;{{$}}
   ~ST() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ST() = default;
+  // CHECK-FIXES: ST() = default;{{$}}
 };
 
 // Deleted constructor/destructor.
@@ -200,7 +214,13 @@
   DC() : KW() {}
   ~DC() override {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~DC() override = default;
+  // CHECK-FIXES: ~DC() override = default;{{$}}
+};
+
+struct OverrideWithSemiColon : KW {
+  ~OverrideWithSemiColon() override {};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~OverrideWithSemiColon() override = default;{{$}}
 };
 
 struct Comments {
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -159,6 +159,7 @@
   with empty body is not equivalent to the explicitly defaulted one, variadic 
constructors
   since they cannot be explicitly defaulted. The check also skips copy 
assignment operators
   with nonstandard return types, private/protected default constructors for 
C++17 or earlier.
+  The automatic fixit has been adjusted to avoid adding superfluous semicolon.
   The check is restricted to C++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -337,10 +337,13 @@
   Diag << MemberType;
 
   if (ApplyFix) {
+SourceLocation UnifiedEnd = utils::lexer::getUnifiedEndLoc(
+*Body, Result.Context->getSourceManager(),
+Result.Context->getLangOpts());
 // Skipping comments, check for a semicolon after Body->getSourceRange()
 Optional Token = utils::lexer::findNextTokenSkippingComments(
-Body->getSourceRange().getEnd().getLocWithOffset(1),
-Result.Context->getSourceManager(), Result.Context->getLangOpts());
+UnifiedEnd, Result.Context->getSourceManager(),
+Result.Context->getLangOpts());
 StringRef Replacement =
 Token && Token->is(tok::semi) ? "= default" : "= default;";
 Diag << FixItHint::CreateReplacement(Body->getSourceRange(), Replacement)


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -91,7 +91,7 @@
 // Private constructor/destructor.
 class Priv {
   Priv();
-  ~Priv() {};
+  ~Priv() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~Priv() = default;
 };
@@ -100,14 +100,28 @@
 // CHECK-ME

[PATCH] D136399: [clang-tidy][modernize-use-equals-default] Avoid adding unnecessary semicolon

2022-10-21 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG6c07bda7a75c: [clang-tidy] Avoid adding unnecessary 
semicolon in modernize-use-equals-default (authored by alexander-shaposhnikov).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136399

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -91,7 +91,7 @@
 // Private constructor/destructor.
 class Priv {
   Priv();
-  ~Priv() {};
+  ~Priv() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~Priv() = default;
 };
@@ -100,14 +100,28 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default'
 // CHECK-FIXES: Priv::Priv() = default;
 
+struct SemiColon {
+  SemiColon() {};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: SemiColon() = default;{{$}}
+};
+
+struct SemiColonOutOfLine {
+  SemiColonOutOfLine();
+};
+
+SemiColonOutOfLine::SemiColonOutOfLine() {};
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: use '= default'
+// CHECK-FIXES: SemiColonOutOfLine::SemiColonOutOfLine() = default;{{$}}
+
 // struct.
 struct ST {
   ST() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ST() = default;
+  // CHECK-FIXES: ST() = default;{{$}}
   ~ST() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ST() = default;
+  // CHECK-FIXES: ST() = default;{{$}}
 };
 
 // Deleted constructor/destructor.
@@ -200,7 +214,13 @@
   DC() : KW() {}
   ~DC() override {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
-  // CHECK-FIXES: ~DC() override = default;
+  // CHECK-FIXES: ~DC() override = default;{{$}}
+};
+
+struct OverrideWithSemiColon : KW {
+  ~OverrideWithSemiColon() override {};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: ~OverrideWithSemiColon() override = default;{{$}}
 };
 
 struct Comments {
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -159,6 +159,7 @@
   with empty body is not equivalent to the explicitly defaulted one, variadic 
constructors
   since they cannot be explicitly defaulted. The check also skips copy 
assignment operators
   with nonstandard return types, private/protected default constructors for 
C++17 or earlier.
+  The automatic fixit has been adjusted to avoid adding superfluous semicolon.
   The check is restricted to C++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -337,10 +337,13 @@
   Diag << MemberType;
 
   if (ApplyFix) {
+SourceLocation UnifiedEnd = utils::lexer::getUnifiedEndLoc(
+*Body, Result.Context->getSourceManager(),
+Result.Context->getLangOpts());
 // Skipping comments, check for a semicolon after Body->getSourceRange()
 Optional Token = utils::lexer::findNextTokenSkippingComments(
-Body->getSourceRange().getEnd().getLocWithOffset(1),
-Result.Context->getSourceManager(), Result.Context->getLangOpts());
+UnifiedEnd, Result.Context->getSourceManager(),
+Result.Context->getLangOpts());
 StringRef Replacement =
 Token && Token->is(tok::semi) ? "= default" : "= default;";
 Diag << FixItHint::CreateReplacement(Body->getSourceRange(), Replacement)


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -91,7 +91,7 @@
 // Private constructor/destructor.
 class Priv {
   Priv();
-  ~Priv() {};
+  ~Priv() {}
   // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
   // CHECK-FIXES: ~Priv() = default;
 };
@@ -100,14 +100,28 @@
 // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use '= default'
 // CHECK-FIXES: Priv::Priv() = default;
 
+struct SemiColon {
+  SemiColon() {};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
+  // CHECK-FIXES: SemiColon() =

[PATCH] D136797: [clang-tidy] Skip template ctors in modernize-use-equals-default

2022-10-26 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov created this revision.
alexander-shaposhnikov added reviewers: gribozavr2, ymandel, LegalizeAdulthood, 
alexfh.
alexander-shaposhnikov created this object with visibility "All Users".
Herald added subscribers: carlosgalvezp, xazax.hun.
Herald added a project: All.
alexander-shaposhnikov requested review of this revision.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Skip template ctors in modernize-use-equals-default,
such constructors may be enabled/disabled via SFINAE,
it is not safe to make them "= default".

Test plan: ninja check-all


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D136797

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -58,6 +58,15 @@
   VA(...) {}
 };
 
+// Skip template constructors.
+struct TA {
+  template 
+  TA() {}
+
+  template 
+  TA(const TA &) {}
+};
+
 // Initializer or arguments.
 class IA {
 public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,9 +158,9 @@
   The check now skips unions/union-like classes since in this case a default 
constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic 
constructors
   since they cannot be explicitly defaulted. The check also skips copy 
assignment operators
-  with nonstandard return types, private/protected default constructors for 
C++17 or earlier.
-  The automatic fixit has been adjusted to avoid adding superfluous semicolon.
-  The check is restricted to C++11 or later.
+  with nonstandard return types, template constructors, private/protected 
default constructors
+  for C++17 or earlier. The automatic fixit has been adjusted to avoid adding 
superfluous
+  semicolon. The check is restricted to C++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
   ` to not
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -246,9 +246,11 @@
   // Default constructor.
   allOf(unless(hasAnyConstructorInitializer(isWritten())),
 unless(isVariadic()), parameterCountIs(0),
+unless(hasParent(functionTemplateDecl())),
 IsPublicOrOutOfLineUntilCPP20),
   // Copy constructor.
   allOf(isCopyConstructor(),
+unless(hasParent(functionTemplateDecl())),
 // Discard constructors that can be used as a copy
 // constructor because all the other arguments have
 // default values.
@@ -257,7 +259,8 @@
   this);
   // Copy-assignment operator.
   Finder->addMatcher(
-  cxxMethodDecl(unless(hasParent(IsUnionLikeClass)), isDefinition(),
+  cxxMethodDecl(unless(hasParent(IsUnionLikeClass)),
+unless(hasParent(functionTemplateDecl())), isDefinition(),
 isCopyAssignmentOperator(),
 // isCopyAssignmentOperator() allows the parameter to be
 // passed by value, and in this case it cannot be


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -58,6 +58,15 @@
   VA(...) {}
 };
 
+// Skip template constructors.
+struct TA {
+  template 
+  TA() {}
+
+  template 
+  TA(const TA &) {}
+};
+
 // Initializer or arguments.
 class IA {
 public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,9 +158,9 @@
   The check now skips unions/union-like classes since in this case a default constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic constructors
   since they cannot be explicitly defaulted. The check also skips copy assignment operators
-  with nonstandard return types, private/protected default constructors for C++17 or earlier.
-  The automatic fixit

[PATCH] D136797: [clang-tidy] Skip template ctors in modernize-use-equals-default

2022-10-27 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov updated this revision to Diff 471304.
alexander-shaposhnikov added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136797

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -58,6 +58,18 @@
   VA(...) {}
 };
 
+// Skip template constructors.
+struct TC {
+  template 
+  TC() {}
+
+  template 
+  TC(const TC &) {}
+
+  template 
+  TC& operator = (const TC &) { return *this; }
+};
+
 // Initializer or arguments.
 class IA {
 public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,9 +158,9 @@
   The check now skips unions/union-like classes since in this case a default 
constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic 
constructors
   since they cannot be explicitly defaulted. The check also skips copy 
assignment operators
-  with nonstandard return types, private/protected default constructors for 
C++17 or earlier.
-  The automatic fixit has been adjusted to avoid adding superfluous semicolon.
-  The check is restricted to C++11 or later.
+  with nonstandard return types, template constructors, private/protected 
default constructors
+  for C++17 or earlier. The automatic fixit has been adjusted to avoid adding 
superfluous
+  semicolon. The check is restricted to C++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
   ` to not
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -241,7 +241,9 @@
   this);
   Finder->addMatcher(
   cxxConstructorDecl(
-  unless(hasParent(IsUnionLikeClass)), isDefinition(),
+  unless(anyOf(hasParent(IsUnionLikeClass),
+   hasParent(functionTemplateDecl(,
+  isDefinition(),
   anyOf(
   // Default constructor.
   allOf(unless(hasAnyConstructorInitializer(isWritten())),
@@ -257,8 +259,9 @@
   this);
   // Copy-assignment operator.
   Finder->addMatcher(
-  cxxMethodDecl(unless(hasParent(IsUnionLikeClass)), isDefinition(),
-isCopyAssignmentOperator(),
+  cxxMethodDecl(unless(anyOf(hasParent(IsUnionLikeClass),
+ hasParent(functionTemplateDecl(,
+isDefinition(), isCopyAssignmentOperator(),
 // isCopyAssignmentOperator() allows the parameter to be
 // passed by value, and in this case it cannot be
 // defaulted.


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -58,6 +58,18 @@
   VA(...) {}
 };
 
+// Skip template constructors.
+struct TC {
+  template 
+  TC() {}
+
+  template 
+  TC(const TC &) {}
+
+  template 
+  TC& operator = (const TC &) { return *this; }
+};
+
 // Initializer or arguments.
 class IA {
 public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,9 +158,9 @@
   The check now skips unions/union-like classes since in this case a default constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic constructors
   since they cannot be explicitly defaulted. The check also skips copy assignment operators
-  with nonstandard return types, private/protected default constructors for C++17 or earlier.
-  The automatic fixit has been adjusted to avoid adding superfluous semicolon.
-  The check is restricted to C++11 or later.
+  with nonstandard return types, template constructors, private/protected default constructors
+  for C++17 or earlier. The automatic fixit has been adjusted to avoid adding superfluous
+  semicolon. The check is restricted to C++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-para

[PATCH] D136797: [clang-tidy] Skip template ctors in modernize-use-equals-default

2022-10-27 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov marked 3 inline comments as done.
alexander-shaposhnikov added inline comments.



Comment at: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp:249
 unless(isVariadic()), parameterCountIs(0),
+unless(hasParent(functionTemplateDecl())),
 IsPublicOrOutOfLineUntilCPP20),

ymandel wrote:
> since this appears in both branches, can you place it above on line 244? that 
> will also save a `hasParent` call (fwiw).
> ```
> unless(hasParent(anyOf(IsUnionLikeClass, functionTemplateDecl(
> ```
(changed to anyOf(hasParent(...)) (hasParent(anyOf(...)) doesn't compile))


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136797

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


[PATCH] D136797: [clang-tidy] Skip template ctors in modernize-use-equals-default

2022-10-27 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
alexander-shaposhnikov updated this revision to Diff 471309.
alexander-shaposhnikov marked an inline comment as done.
alexander-shaposhnikov added a comment.

Address comments


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136797

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -58,6 +58,18 @@
   VA(...) {}
 };
 
+// Skip template constructors.
+struct TC {
+  template 
+  TC() {}
+
+  template 
+  TC(const TC &) {}
+
+  template 
+  TC& operator = (const TC &) { return *this; }
+};
+
 // Initializer or arguments.
 class IA {
 public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,9 +158,9 @@
   The check now skips unions/union-like classes since in this case a default 
constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic 
constructors
   since they cannot be explicitly defaulted. The check also skips copy 
assignment operators
-  with nonstandard return types, private/protected default constructors for 
C++17 or earlier.
-  The automatic fixit has been adjusted to avoid adding superfluous semicolon.
-  The check is restricted to C++11 or later.
+  with nonstandard return types, template constructors, private/protected 
default constructors
+  for C++17 or earlier. The automatic fixit has been adjusted to avoid adding 
superfluous
+  semicolon. The check is restricted to C++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
   ` to not
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -241,7 +241,9 @@
   this);
   Finder->addMatcher(
   cxxConstructorDecl(
-  unless(hasParent(IsUnionLikeClass)), isDefinition(),
+  unless(
+  hasParent(decl(anyOf(IsUnionLikeClass, 
functionTemplateDecl(),
+  isDefinition(),
   anyOf(
   // Default constructor.
   allOf(unless(hasAnyConstructorInitializer(isWritten())),
@@ -257,8 +259,9 @@
   this);
   // Copy-assignment operator.
   Finder->addMatcher(
-  cxxMethodDecl(unless(hasParent(IsUnionLikeClass)), isDefinition(),
-isCopyAssignmentOperator(),
+  cxxMethodDecl(unless(hasParent(
+decl(anyOf(IsUnionLikeClass, 
functionTemplateDecl(),
+isDefinition(), isCopyAssignmentOperator(),
 // isCopyAssignmentOperator() allows the parameter to be
 // passed by value, and in this case it cannot be
 // defaulted.


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -58,6 +58,18 @@
   VA(...) {}
 };
 
+// Skip template constructors.
+struct TC {
+  template 
+  TC() {}
+
+  template 
+  TC(const TC &) {}
+
+  template 
+  TC& operator = (const TC &) { return *this; }
+};
+
 // Initializer or arguments.
 class IA {
 public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,9 +158,9 @@
   The check now skips unions/union-like classes since in this case a default constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic constructors
   since they cannot be explicitly defaulted. The check also skips copy assignment operators
-  with nonstandard return types, private/protected default constructors for C++17 or earlier.
-  The automatic fixit has been adjusted to avoid adding superfluous semicolon.
-  The check is restricted to C++11 or later.
+  with nonstandard return types, template constructors, private/protected default constructors
+  for C++17 or earlier. The automatic fixit has been adjusted to avoid adding superfluous
+  semicolon. The check is restricted to C++11 or later.
 
 - Change the default behavior of :

[PATCH] D136797: [clang-tidy] Skip template ctors in modernize-use-equals-default

2022-10-27 Thread Alexander Shaposhnikov via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG29e4606ced72: [clang-tidy] Skip template ctors in 
modernize-use-equals-default (authored by alexander-shaposhnikov).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D136797

Files:
  clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp


Index: 
clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -58,6 +58,18 @@
   VA(...) {}
 };
 
+// Skip template constructors.
+struct TC {
+  template 
+  TC() {}
+
+  template 
+  TC(const TC &) {}
+
+  template 
+  TC& operator = (const TC &) { return *this; }
+};
+
 // Initializer or arguments.
 class IA {
 public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,9 +158,9 @@
   The check now skips unions/union-like classes since in this case a default 
constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic 
constructors
   since they cannot be explicitly defaulted. The check also skips copy 
assignment operators
-  with nonstandard return types, private/protected default constructors for 
C++17 or earlier.
-  The automatic fixit has been adjusted to avoid adding superfluous semicolon.
-  The check is restricted to C++11 or later.
+  with nonstandard return types, template constructors, private/protected 
default constructors
+  for C++17 or earlier. The automatic fixit has been adjusted to avoid adding 
superfluous
+  semicolon. The check is restricted to C++11 or later.
 
 - Change the default behavior of :doc:`readability-avoid-const-params-in-decls
   ` to not
Index: clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
===
--- clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -241,7 +241,9 @@
   this);
   Finder->addMatcher(
   cxxConstructorDecl(
-  unless(hasParent(IsUnionLikeClass)), isDefinition(),
+  unless(
+  hasParent(decl(anyOf(IsUnionLikeClass, 
functionTemplateDecl(),
+  isDefinition(),
   anyOf(
   // Default constructor.
   allOf(unless(hasAnyConstructorInitializer(isWritten())),
@@ -257,8 +259,9 @@
   this);
   // Copy-assignment operator.
   Finder->addMatcher(
-  cxxMethodDecl(unless(hasParent(IsUnionLikeClass)), isDefinition(),
-isCopyAssignmentOperator(),
+  cxxMethodDecl(unless(hasParent(
+decl(anyOf(IsUnionLikeClass, 
functionTemplateDecl(),
+isDefinition(), isCopyAssignmentOperator(),
 // isCopyAssignmentOperator() allows the parameter to be
 // passed by value, and in this case it cannot be
 // defaulted.


Index: clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/modernize/use-equals-default.cpp
@@ -58,6 +58,18 @@
   VA(...) {}
 };
 
+// Skip template constructors.
+struct TC {
+  template 
+  TC() {}
+
+  template 
+  TC(const TC &) {}
+
+  template 
+  TC& operator = (const TC &) { return *this; }
+};
+
 // Initializer or arguments.
 class IA {
 public:
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,9 +158,9 @@
   The check now skips unions/union-like classes since in this case a default constructor
   with empty body is not equivalent to the explicitly defaulted one, variadic constructors
   since they cannot be explicitly defaulted. The check also skips copy assignment operators
-  with nonstandard return types, private/protected default constructors for C++17 or earlier.
-  The automatic fixit has been adjusted to avoid adding superfluous semicolon.
-  The check is restricted to C++11 or later.
+  with nonstandard return types, template constructors, private/protected default constructors
+  for C++17 or earlier. The automatic fixit has been adjusted to avoid adding superfluous
+  semicolon. The check is restricted to C++11 or later.
 
 

  1   2   3   4   >