r368929 - [LifetimeAnalysis] Support std::stack::top() and std::optional::value()

2019-08-14 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Wed Aug 14 14:55:57 2019
New Revision: 368929

URL: http://llvm.org/viewvc/llvm-project?rev=368929&view=rev
Log:
[LifetimeAnalysis] Support std::stack::top() and std::optional::value()

Summary: Diagnose dangling pointers that come from std::stack::top() and 
std::optional::value().

Reviewers: gribozavr

Subscribers: cfe-commits, xazax.hun

Tags: #clang

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

Modified:
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=368929&r1=368928&r2=368929&view=diff
==
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Wed Aug 14 14:55:57 2019
@@ -6610,7 +6610,7 @@ static bool shouldTrackImplicitObjectArg
  OO == OverloadedOperatorKind::OO_Star;
 }
 return llvm::StringSwitch(Callee->getName())
-.Cases("front", "back", "at", true)
+.Cases("front", "back", "at", "top", "value", true)
 .Default(false);
   }
   return false;

Modified: cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp?rev=368929&r1=368928&r2=368929&view=diff
==
--- cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp (original)
+++ cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp Wed Aug 14 14:55:57 
2019
@@ -170,7 +170,15 @@ template
 struct optional {
   optional();
   optional(const T&);
-  T &operator*();
+  T &operator*() &;
+  T &&operator*() &&;
+  T &value() &;
+  T &&value() &&;
+};
+
+template
+struct stack {
+  T &top();
 };
 }
 
@@ -188,6 +196,16 @@ const char *danglingRawPtrFromLocal() {
   return s.c_str(); // expected-warning {{address of stack memory associated 
with local variable 's' returned}}
 }
 
+int &danglingRawPtrFromLocal2() {
+  std::optional o;
+  return o.value(); // expected-warning {{reference to stack memory associated 
with local variable 'o' returned}}
+}
+
+int &danglingRawPtrFromLocal3() {
+  std::optional o;
+  return *o; // expected-warning {{reference to stack memory associated with 
local variable 'o' returned}}
+}
+
 const char *danglingRawPtrFromTemp() {
   return std::basic_string().c_str(); // expected-warning {{returning 
address of local temporary object}}
 }
@@ -203,9 +221,10 @@ int *danglingUniquePtrFromTemp2() {
 }
 
 void danglingReferenceFromTempOwner() {
-  int &r = *std::optional(); // expected-warning {{object backing the 
pointer will be destroyed at the end of the full-expression}}
-  int &r2 = *std::optional(5); // expected-warning {{object backing the 
pointer will be destroyed at the end of the full-expression}}
-  int &r3 = std::vector().at(3); // expected-warning {{object backing the 
pointer will be destroyed at the end of the full-expression}}
+  int &&r = *std::optional();  // expected-warning {{object 
backing the pointer will be destroyed at the end of the full-expression}}
+  int &&r2 = *std::optional(5);// expected-warning {{object 
backing the pointer will be destroyed at the end of the full-expression}}
+  int &&r3 = std::optional(5).value(); // expected-warning {{object 
backing the pointer will be destroyed at the end of the full-expression}}
+  int &r4 = std::vector().at(3);   // expected-warning {{object 
backing the pointer will be destroyed at the end of the full-expression}}
 }
 
 std::vector getTempVec();


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


r369591 - [LifetimeAnalysis] Support more STL idioms (template forward declaration and DependentNameType)

2019-08-21 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Wed Aug 21 15:08:59 2019
New Revision: 369591

URL: http://llvm.org/viewvc/llvm-project?rev=369591&view=rev
Log:
[LifetimeAnalysis] Support more STL idioms (template forward declaration and 
DependentNameType)

Summary:
This fixes inference of gsl::Pointer on std::set::iterator with libstdc++ (the 
typedef for iterator
on the template is a DependentNameType - we can only put the gsl::Pointer 
attribute
on the underlaying record after instantiation)

inference of gsl::Pointer on std::vector::iterator with libc++ (the class was 
forward-declared,
we added the gsl::Pointer on the canonical decl (the forward decl), and later 
when the
template was instantiated, there was no attribute on the definition so it was 
not instantiated).

and a duplicate gsl::Pointer on some class with libstdc++ (we first added an 
attribute to
a incomplete instantiation, and then another was copied from the template 
definition
when the instantiation was completed).

We now add the attributes to all redeclarations to fix thos issues and make 
their usage easier.

Reviewers: gribozavr

Subscribers: Szelethus, xazax.hun, cfe-commits

Tags: #clang

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

Added:
cfe/trunk/unittests/Sema/GslOwnerPointerInference.cpp
Modified:
cfe/trunk/lib/Sema/SemaAttr.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/attr-gsl-owner-pointer-std.cpp
cfe/trunk/test/SemaCXX/attr-gsl-owner-pointer.cpp
cfe/trunk/unittests/Sema/CMakeLists.txt

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=369591&r1=369590&r2=369591&view=diff
==
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Wed Aug 21 15:08:59 2019
@@ -88,13 +88,11 @@ void Sema::AddMsStructLayoutForRecord(Re
 template 
 static void addGslOwnerPointerAttributeIfNotExisting(ASTContext &Context,
  CXXRecordDecl *Record) {
-  CXXRecordDecl *Canonical = Record->getCanonicalDecl();
-  if (Canonical->hasAttr() || Canonical->hasAttr())
+  if (Record->hasAttr() || Record->hasAttr())
 return;
 
-  Canonical->addAttr(::new (Context) Attribute(SourceRange{}, Context,
-   /*DerefType*/ nullptr,
-   /*Spelling=*/0));
+  for (Decl *Redecl : Record->redecls())
+Redecl->addAttr(Attribute::CreateImplicit(Context, /*DerefType=*/nullptr));
 }
 
 void Sema::inferGslPointerAttribute(NamedDecl *ND,
@@ -189,8 +187,7 @@ void Sema::inferGslOwnerPointerAttribute
 
   // Handle classes that directly appear in std namespace.
   if (Record->isInStdNamespace()) {
-CXXRecordDecl *Canonical = Record->getCanonicalDecl();
-if (Canonical->hasAttr() || Canonical->hasAttr())
+if (Record->hasAttr() || Record->hasAttr())
   return;
 
 if (StdOwners.count(Record->getName()))

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=369591&r1=369590&r2=369591&view=diff
==
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Aug 21 15:08:59 2019
@@ -4592,9 +4592,11 @@ static void handleLifetimeCategoryAttr(S
   }
   return;
 }
-D->addAttr(::new (S.Context)
-   OwnerAttr(AL.getRange(), S.Context, DerefTypeLoc,
- AL.getAttributeSpellingListIndex()));
+for (Decl *Redecl : D->redecls()) {
+  Redecl->addAttr(::new (S.Context)
+  OwnerAttr(AL.getRange(), S.Context, DerefTypeLoc,
+AL.getAttributeSpellingListIndex()));
+}
   } else {
 if (checkAttrMutualExclusion(S, D, AL))
   return;
@@ -4609,9 +4611,11 @@ static void handleLifetimeCategoryAttr(S
   }
   return;
 }
-D->addAttr(::new (S.Context)
-   PointerAttr(AL.getRange(), S.Context, DerefTypeLoc,
-   AL.getAttributeSpellingListIndex()));
+for (Decl *Redecl : D->redecls()) {
+  Redecl->addAttr(::new (S.Context)
+  PointerAttr(AL.getRange(), S.Context, DerefTypeLoc,
+  AL.getAttributeSpellingListIndex()));
+}
   }
 }
 

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=369591&r1=369590&r2=369591&view=diff
==
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Wed Aug 21 15:08:59 2019
@@ -6561,7 +6561,7 @@ static void visitLocalsRetainedByR

Re: r369591 - [LifetimeAnalysis] Support more STL idioms (template forward declaration and DependentNameType)

2019-08-22 Thread Matthias Gehre via cfe-commits
Hi Diana,
hi Richard,

thank you for the feedback!

Diana,
I remember that some gcc version had issues with raw string literals inside
macros. I'll fix that to use normal
string literals instead.

Richard,
We are definitely want the gsl::Pointer-based warnings that are enabled by
default to be free of any false-positives.
As you expected, this is showing a problem we have in another part of our
analysis, and we will fix it before landing
this PR again.

Both, sorry for the breakage!

Am Do., 22. Aug. 2019 um 19:47 Uhr schrieb Richard Smith <
rich...@metafoo.co.uk>:

> Reverted in r369677.
>
> On Thu, 22 Aug 2019 at 10:34, Richard Smith  wrote:
>
>> Hi Matthias,
>>
>> This introduces false positives into -Wreturn-stack-address for an
>> example such as:
>>
>> #include 
>>
>> std::vector::iterator downcast_to(std::vector::iterator value) {
>>   return *&value;
>> }
>>
>> This breaks an internal build bot for us, so I'm going to revert this for
>> now (though I expect this isn't the cause of the problem, but is rather
>> exposing a problem elsewhere).
>>
>> If we can make the gsl::Pointer diagnostics false-positive-free, that's
>> great, but otherwise we should use a different warning flag for the
>> warnings that involve these annotations and use -Wreturn-stack-address for
>> only the zero-false-positive cases that it historically diagnosed.
>>
>> Thanks, and sorry for the trouble.
>>
>> On Wed, 21 Aug 2019 at 15:07, Matthias Gehre via cfe-commits <
>> cfe-commits@lists.llvm.org> wrote:
>>
>>> Author: mgehre
>>> Date: Wed Aug 21 15:08:59 2019
>>> New Revision: 369591
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=369591&view=rev
>>> Log:
>>> [LifetimeAnalysis] Support more STL idioms (template forward declaration
>>> and DependentNameType)
>>>
>>> Summary:
>>> This fixes inference of gsl::Pointer on std::set::iterator with
>>> libstdc++ (the typedef for iterator
>>> on the template is a DependentNameType - we can only put the
>>> gsl::Pointer attribute
>>> on the underlaying record after instantiation)
>>>
>>> inference of gsl::Pointer on std::vector::iterator with libc++ (the
>>> class was forward-declared,
>>> we added the gsl::Pointer on the canonical decl (the forward decl), and
>>> later when the
>>> template was instantiated, there was no attribute on the definition so
>>> it was not instantiated).
>>>
>>> and a duplicate gsl::Pointer on some class with libstdc++ (we first
>>> added an attribute to
>>> a incomplete instantiation, and then another was copied from the
>>> template definition
>>> when the instantiation was completed).
>>>
>>> We now add the attributes to all redeclarations to fix thos issues and
>>> make their usage easier.
>>>
>>> Reviewers: gribozavr
>>>
>>> Subscribers: Szelethus, xazax.hun, cfe-commits
>>>
>>> Tags: #clang
>>>
>>> Differential Revision: https://reviews.llvm.org/D66179
>>>
>>> Added:
>>> cfe/trunk/unittests/Sema/GslOwnerPointerInference.cpp
>>> Modified:
>>> cfe/trunk/lib/Sema/SemaAttr.cpp
>>> cfe/trunk/lib/Sema/SemaDeclAttr.cpp
>>> cfe/trunk/lib/Sema/SemaInit.cpp
>>> cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
>>> cfe/trunk/test/SemaCXX/attr-gsl-owner-pointer-std.cpp
>>> cfe/trunk/test/SemaCXX/attr-gsl-owner-pointer.cpp
>>> cfe/trunk/unittests/Sema/CMakeLists.txt
>>>
>>> Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
>>> URL:
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=369591&r1=369590&r2=369591&view=diff
>>>
>>> ==
>>> --- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaAttr.cpp Wed Aug 21 15:08:59 2019
>>> @@ -88,13 +88,11 @@ void Sema::AddMsStructLayoutForRecord(Re
>>>  template 
>>>  static void addGslOwnerPointerAttributeIfNotExisting(ASTContext
>>> &Context,
>>>   CXXRecordDecl
>>> *Record) {
>>> -  CXXRecordDecl *Canonical = Record->getCanonicalDecl();
>>> -  if (Canonical->hasAttr() ||
>>> Canonical->hasAttr())
>>> +  if (Record->hasAttr() || Record->hasAttr())
>>>  return;
>>>
>>

[clang-tools-extra] r366265 - [clang-tidy] initial version of readability-convert-member-functions-to-static

2019-07-16 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Tue Jul 16 14:19:00 2019
New Revision: 366265

URL: http://llvm.org/viewvc/llvm-project?rev=366265&view=rev
Log:
[clang-tidy] initial version of readability-convert-member-functions-to-static

Summary:
Finds non-static member functions that can be made ``static``.

I have run this check (repeatedly) over llvm-project. It made 1708 member 
functions
``static``. Out of those, I had to exclude 22 via ``NOLINT`` because their 
address
was taken and stored in a variable of pointer-to-member type (e.g. passed to
llvm::StringSwitch).
It also made 243 member functions ``const``. (This is currently very 
conservative
to have no false-positives and can hopefully be extended in the future.)

You can find the results here: 
https://github.com/mgehre/llvm-project/commits/static_const_eval

Reviewers: alexfh, aaron.ballman

Subscribers: mgorny, xazax.hun, cfe-commits

Tags: #clang

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

Added:

clang-tools-extra/trunk/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp

clang-tools-extra/trunk/clang-tidy/readability/ConvertMemberFunctionsToStatic.h

clang-tools-extra/trunk/docs/clang-tidy/checks/readability-convert-member-functions-to-static.rst

clang-tools-extra/trunk/test/clang-tidy/readability-convert-member-functions-to-static.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt
clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp
clang-tools-extra/trunk/docs/ReleaseNotes.rst
clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt?rev=366265&r1=366264&r2=366265&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt Tue Jul 16 
14:19:00 2019
@@ -5,6 +5,7 @@ add_clang_library(clangTidyReadabilityMo
   BracesAroundStatementsCheck.cpp
   ConstReturnTypeCheck.cpp
   ContainerSizeEmptyCheck.cpp
+  ConvertMemberFunctionsToStatic.cpp
   DeleteNullPointerCheck.cpp
   DeletedDefaultCheck.cpp
   ElseAfterReturnCheck.cpp

Added: 
clang-tools-extra/trunk/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp?rev=366265&view=auto
==
--- 
clang-tools-extra/trunk/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp
 (added)
+++ 
clang-tools-extra/trunk/clang-tidy/readability/ConvertMemberFunctionsToStatic.cpp
 Tue Jul 16 14:19:00 2019
@@ -0,0 +1,172 @@
+//===--- ConvertMemberFunctionsToStatic.cpp - clang-tidy 
--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ConvertMemberFunctionsToStatic.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/SourceLocation.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); }
+
+AST_MATCHER(CXXMethodDecl, hasTrivialBody) { return Node.hasTrivialBody(); }
+
+AST_MATCHER(CXXMethodDecl, isOverloadedOperator) {
+  return Node.isOverloadedOperator();
+}
+
+AST_MATCHER(CXXRecordDecl, hasAnyDependentBases) {
+  return Node.hasAnyDependentBases();
+}
+
+AST_MATCHER(CXXMethodDecl, isTemplate) {
+  return Node.getTemplatedKind() != FunctionDecl::TK_NonTemplate;
+}
+
+AST_MATCHER(CXXMethodDecl, isDependentContext) {
+  return Node.isDependentContext();
+}
+
+AST_MATCHER(CXXMethodDecl, isInsideMacroDefinition) {
+  const ASTContext &Ctxt = Finder->getASTContext();
+  return clang::Lexer::makeFileCharRange(
+ clang::CharSourceRange::getCharRange(
+ Node.getTypeSourceInfo()->getTypeLoc().getSourceRange()),
+ Ctxt.getSourceManager(), Ctxt.getLangOpts())
+  .isInvalid();
+}
+
+AST_MATCHER_P(CXXMethodDecl, hasCanonicalDecl,
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder);
+}
+
+AST_MATCHER(CXXMethodDecl, usesThis) {
+  class FindUsageOfThis : public RecursiveASTVisitor {
+  public:
+bool Used = false;
+
+bool VisitCXXThisExpr(const CXXThisExpr *E) {
+  Used = true;
+  return false; // Stop traversal.
+}
+  } UsageOfThis;
+
+  // TraverseStmt does not modify its argu

[clang-tools-extra] eaa5559 - [clang-tidy] misc-unused-parameters: Don't remove parameter from lambda

2020-04-09 Thread Matthias Gehre via cfe-commits

Author: Matthias Gehre
Date: 2020-04-09T19:26:41+02:00
New Revision: eaa55590945a130131a47a4d2b89e3bbdfced79e

URL: 
https://github.com/llvm/llvm-project/commit/eaa55590945a130131a47a4d2b89e3bbdfced79e
DIFF: 
https://github.com/llvm/llvm-project/commit/eaa55590945a130131a47a4d2b89e3bbdfced79e.diff

LOG: [clang-tidy] misc-unused-parameters: Don't remove parameter from lambda

Summary:
Previously, the check would fix
```
using fn = void(int);
void f(fn *);
void test() {
  // CHECK-MESSAGES: :[[@LINE+2]]:12: warning: parameter 'I' is unused
  // CHECK-FIXES: {{^}}  f([](int  /*I*/) {
  f([](int I) { return; });
}
```
into
`f([]() { return; });` which breaks compilation. Now the check is disabled from 
Lambdas.

The AST is not so easy to use. For
```
auto l = [](int) {  return;  };
f(l);
```
one gets
```
 `-CallExpr  'void'
  |-ImplicitCastExpr  'void (*)(fn *)' 
  | `-DeclRefExpr  'void (fn *)' lvalue Function 0x55a91a545e28 'f' 
'void (fn *)'
  `-ImplicitCastExpr  'void (*)(int)' 
`-CXXMemberCallExpr  'void (*)(int)'
  `-MemberExpr  '' .operator void 
(*)(int) 0x55a91a546850
`-ImplicitCastExpr  'const (lambda at line:6:14)' lvalue 

  `-DeclRefExpr  '(lambda at line:6:14)':'(lambda at 
line:6:14)' lvalue Var 0x55a91a5461c0 'l' '(lambda at line:6:14)':'(lambda at 
line:6:14)'
```
There is no direct use of the `operator()(int I)` of the lambda, so the 
`!Indexer->getOtherRefs(Function).empty()`
does not fire. In the future, we might be able to use the conversion operator 
`operator void (*)(int)` to mark
the call operator as having an "other ref".

Reviewers: aaron.ballman, alexfh, hokein, njames93

Subscribers: xazax.hun, cfe-commits

Tags: #clang

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp
index 9514c044277f..b1507ed81ba7 100644
--- a/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UnusedParametersCheck.cpp
@@ -8,6 +8,7 @@
 
 #include "UnusedParametersCheck.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/Lex/Lexer.h"
@@ -141,7 +142,8 @@ void UnusedParametersCheck::warnOnUnusedParameter(
   // Cannot remove parameter for non-local functions.
   if (Function->isExternallyVisible() ||
   !Result.SourceManager->isInMainFile(Function->getLocation()) ||
-  !Indexer->getOtherRefs(Function).empty() || isOverrideMethod(Function)) {
+  !Indexer->getOtherRefs(Function).empty() || isOverrideMethod(Function) ||
+  isLambdaCallOperator(Function)) {
 
 // It is illegal to omit parameter name here in C code, so early-out.
 if (!Result.Context->getLangOpts().CPlusPlus)

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp
index 8e546b44ab74..52f9675bffa1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc-unused-parameters.cpp
@@ -276,3 +276,13 @@ class B : public A {
 // CHECK-FIXES: {{^}}  B(int  /*i*/) : A() {}{{$}}
 };
 } // namespace strict_mode_off
+
+namespace lambda {
+using fn = void(int);
+void f(fn *);
+void test() {
+  // CHECK-MESSAGES: :[[@LINE+2]]:12: warning: parameter 'I' is unused
+  // CHECK-FIXES: {{^}}  f([](int  /*I*/) {
+  f([](int I) { return; });
+}
+} // namespace lambda



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


[clang] 0642e5e - [clang-tidy] modernize-use-using: Fix broken fixit with 'template' keyword

2020-04-17 Thread Matthias Gehre via cfe-commits

Author: Matthias Gehre
Date: 2020-04-17T10:37:24+02:00
New Revision: 0642e5e7a7e54a11120262cfafea0193e3a75faf

URL: 
https://github.com/llvm/llvm-project/commit/0642e5e7a7e54a11120262cfafea0193e3a75faf
DIFF: 
https://github.com/llvm/llvm-project/commit/0642e5e7a7e54a11120262cfafea0193e3a75faf.diff

LOG: [clang-tidy] modernize-use-using: Fix broken fixit with 'template' keyword

Summary:
Before this PR, `modernize-use-using` would transform the typedef in
```

template  class TemplateKeyword {
  typedef typename a::template f<> e;
  typedef typename a::template f<>::d e2;
};
```
into
```
template  class TemplateKeyword {
  using d = typename a::b<>;
  using d2 = typename a::template a::b<>::c;
};
```
The first one is missing the `template` keyword,
the second one has an extra `a::` scope. Both result
in compilation errors.

Reviewers: aaron.ballman, alexfh, hokein, njames93

Subscribers: xazax.hun, cfe-commits

Tags: #clang

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

Added: 


Modified: 
clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
clang/lib/AST/NestedNameSpecifier.cpp
clang/lib/AST/TypePrinter.cpp
clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp

Removed: 




diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
index 2eccc9066fa6..8d25dbb95658 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
@@ -249,6 +249,17 @@ typedef TwoArgTemplate 
>, S<(0 < 0), Q>, S<(0 < 0), Q>>;
 
+template 
+class TemplateKeyword {
+  typedef typename a::template b<> d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
+  // CHECK-FIXES: using d = typename a::template b<>;
+
+  typedef typename a::template b<>::c d2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
+  // CHECK-FIXES: using d2 = typename a::template b<>::c;
+};
+
 template 
 class Variadic {};
 

diff  --git a/clang/lib/AST/NestedNameSpecifier.cpp 
b/clang/lib/AST/NestedNameSpecifier.cpp
index af53c7fd9ba4..e28463516a9f 100644
--- a/clang/lib/AST/NestedNameSpecifier.cpp
+++ b/clang/lib/AST/NestedNameSpecifier.cpp
@@ -311,6 +311,14 @@ void NestedNameSpecifier::print(raw_ostream &OS, const 
PrintingPolicy &Policy,
   // Print the template argument list.
   printTemplateArgumentList(OS, SpecType->template_arguments(),
 InnerPolicy);
+} else if (const auto *DepSpecType =
+   dyn_cast(T)) {
+  // Print the template name without its corresponding
+  // nested-name-specifier.
+  OS << DepSpecType->getIdentifier()->getName();
+  // Print the template argument list.
+  printTemplateArgumentList(OS, DepSpecType->template_arguments(),
+InnerPolicy);
 } else {
   // Print the type normally
   QualType(T, 0).print(OS, InnerPolicy);

diff  --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 405a760c58ce..4cc0d735ed6a 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1388,7 +1388,7 @@ void 
TypePrinter::printDependentTemplateSpecializationBefore(
 
   if (T->getQualifier())
 T->getQualifier()->print(OS, Policy);
-  OS << T->getIdentifier()->getName();
+  OS << "template " << T->getIdentifier()->getName();
   printTemplateArgumentList(OS, T->template_arguments(), Policy);
   spaceBeforePlaceHolder(OS);
 }

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp 
b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
index b8903b884e0a..15cbe6637845 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
@@ -109,9 +109,9 @@ static_assert(!requires { typename ::F; });
 struct G { template static T temp; };
 
 template requires requires { typename T::template temp; }
-// expected-note@-1{{because 'typename T::temp' would be invalid: type 
'int' cannot be used prior to '::' because it has no members}}
-// expected-note@-2{{because 'typename T::temp' would be invalid: no 
member named 'temp' in 'D'}}
-// expected-note@-3{{because 'typename T::temp' would be invalid: 
template name refers to non-type template 'G::template temp'}}
+// expected-note@-1{{because 'typename T::template temp' would be 
invalid: type 'int' cannot be used prior to '::' because it has no members}}
+// expected-note@-2{{because 'typename T::template temp' would be 
invalid: no member named 'temp' in 'D'}}
+// expected-note@-3{{because 'typename T::template temp' would be 
invalid: template name refers to non-type template 'G::template temp'}}
 struct r7 {};
 
 using r7i1 = r7; // expected-error

[clang] 145dcef - [clang-tidy] modernize-use-using: Fix broken fixit with InjectedClassName

2020-04-27 Thread Matthias Gehre via cfe-commits

Author: Matthias Gehre
Date: 2020-04-27T14:23:23+02:00
New Revision: 145dcef8bdf9da9684c9c4e34a8e6c45baafab74

URL: 
https://github.com/llvm/llvm-project/commit/145dcef8bdf9da9684c9c4e34a8e6c45baafab74
DIFF: 
https://github.com/llvm/llvm-project/commit/145dcef8bdf9da9684c9c4e34a8e6c45baafab74.diff

LOG: [clang-tidy] modernize-use-using: Fix broken fixit with InjectedClassName

Summary:
Before this PR, `modernize-use-using` would transform the typedef in
```
template 
struct InjectedClassName {
  typedef InjectedClassName b;
};
```
into `using b = InjectedClassName;` and
```
template 
struct InjectedClassNameWithUnnamedArgument {
  typedef InjectedClassNameWithUnnamedArgument b;
};
```
into `using b = InjectedClassNameWithUnnamedArgument<>;`.
The first fixit is surprising because its different than the code
before, but the second fixit doesn't even compile.

This PR adds an option to the TypePrinter to print InjectedClassNameType without
template parameters (i.e. as written).

Reviewers: aaron.ballman, alexfh, hokein, njames93

Subscribers: xazax.hun, cfe-commits

Tags: #clang

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
clang/include/clang/AST/PrettyPrinter.h
clang/lib/AST/TypePrinter.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
index f352374d4b91..f6dc5c044a7a 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
@@ -58,6 +58,7 @@ void UseUsingCheck::check(const MatchFinder::MatchResult 
&Result) {
   printPolicy.SuppressScope = true;
   printPolicy.ConstantArraySizeAsWritten = true;
   printPolicy.UseVoidForZeroParams = false;
+  printPolicy.PrintInjectedClassNameWithArguments = false;
 
   std::string Type = MatchedDecl->getUnderlyingType().getAsString(printPolicy);
   std::string Name = MatchedDecl->getNameAsString();

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
index 8d25dbb95658..b74e67a17f86 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp
@@ -289,3 +289,16 @@ typedef enum { ea2, eb2 } 
EnumT2_CheckTypedefImpactFromAnotherFile;
 // CHECK-MESSAGES: :[[@LINE-1]]:1: warning: use 'using' instead of 'typedef'
 // CHECK-FIXES: using EnumT2_CheckTypedefImpactFromAnotherFile = enum { ea2, 
eb2 };
 
+template 
+struct InjectedClassName {
+  typedef InjectedClassName b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
+  // CHECK-FIXES: using b = InjectedClassName;
+};
+
+template 
+struct InjectedClassNameWithUnnamedArgument {
+  typedef InjectedClassNameWithUnnamedArgument b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use 'using' instead of 'typedef'
+  // CHECK-FIXES: using b = InjectedClassNameWithUnnamedArgument;
+};

diff  --git a/clang/include/clang/AST/PrettyPrinter.h 
b/clang/include/clang/AST/PrettyPrinter.h
index 21e5ca94f6c4..65c7e2385677 100644
--- a/clang/include/clang/AST/PrettyPrinter.h
+++ b/clang/include/clang/AST/PrettyPrinter.h
@@ -63,7 +63,7 @@ struct PrintingPolicy {
 MSWChar(LO.MicrosoftExt && !LO.WChar), IncludeNewlines(true),
 MSVCFormatting(false), ConstantsAsWritten(false),
 SuppressImplicitBase(false), FullyQualifiedName(false),
-PrintCanonicalTypes(false) {}
+PrintCanonicalTypes(false), PrintInjectedClassNameWithArguments(true) 
{}
 
   /// Adjust this printing policy for cases where it's known that we're
   /// printing C++ code (for instance, if AST dumping reaches a C++-only
@@ -244,6 +244,11 @@ struct PrintingPolicy {
   /// Whether to print types as written or canonically.
   unsigned PrintCanonicalTypes : 1;
 
+  /// Whether to print an InjectedClassNameType with template arguments or as
+  /// written. When a template argument is unnamed, printing it results in
+  /// invalid C++ code.
+  unsigned PrintInjectedClassNameWithArguments : 1;
+
   /// Callbacks to use to allow the behavior of printing to be customized.
   const PrintingCallbacks *Callbacks = nullptr;
 };

diff  --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index f000e1f6c932..cf82d1a26156 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1329,7 +1329,12 @@ void TypePrinter::printTemplateSpecializationAfter(
 
 void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
raw_ostream &OS) {
-  printTemplateSpecializationBefore(T->getInjectedTST(), OS);
+  if (Policy.PrintInj

[clang-tools-extra] add51e1 - [clang-tidy] add new check readability-use-anyofallof

2020-06-03 Thread Matthias Gehre via cfe-commits

Author: Matthias Gehre
Date: 2020-06-03T12:19:06+02:00
New Revision: add51e152aa6dc3aa7a51901a099b2ebe8cfe377

URL: 
https://github.com/llvm/llvm-project/commit/add51e152aa6dc3aa7a51901a099b2ebe8cfe377
DIFF: 
https://github.com/llvm/llvm-project/commit/add51e152aa6dc3aa7a51901a099b2ebe8cfe377.diff

LOG: [clang-tidy] add new check readability-use-anyofallof

Summary:
Finds range-based for loops that can be replaced by a call to ``std::any_of`` or
``std::all_of``. In C++ 20 mode, suggests ``std::ranges::any_of`` or
``std::ranges::all_of``.
For now, no fixits are produced.

Reviewers: aaron.ballman, alexfh, hokein

Subscribers: mgorny, xazax.hun, cfe-commits

Tags: #clang

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

Added: 
clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.cpp
clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.h
clang-tools-extra/docs/clang-tidy/checks/readability-use-anyofallof.rst

clang-tools-extra/test/clang-tidy/checkers/readability-use-anyofallof-cpp20.cpp
clang-tools-extra/test/clang-tidy/checkers/readability-use-anyofallof.cpp

Modified: 
clang-tools-extra/clang-tidy/readability/CMakeLists.txt
clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 5f674beaa8be..02003a7537f0 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -42,8 +42,10 @@ add_clang_library(clangTidyReadabilityModule
   StringCompareCheck.cpp
   UniqueptrDeleteReleaseCheck.cpp
   UppercaseLiteralSuffixCheck.cpp
+  UseAnyOfAllOfCheck.cpp
 
   LINK_LIBS
+  clangAnalysis
   clangAST
   clangASTMatchers
   clangBasic

diff  --git 
a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp 
b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index 5ece15ed2912..5ff5e2022839 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -45,6 +45,7 @@
 #include "StringCompareCheck.h"
 #include "UniqueptrDeleteReleaseCheck.h"
 #include "UppercaseLiteralSuffixCheck.h"
+#include "UseAnyOfAllOfCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -125,6 +126,8 @@ class ReadabilityModule : public ClangTidyModule {
 "readability-uniqueptr-delete-release");
 CheckFactories.registerCheck(
 "readability-uppercase-literal-suffix");
+CheckFactories.registerCheck(
+"readability-use-anyofallof");
   }
 };
 

diff  --git a/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.cpp
new file mode 100644
index ..d3c002f5ad1d
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UseAnyOfAllOfCheck.cpp
@@ -0,0 +1,109 @@
+//===--- UseAnyOfAllOfCheck.cpp - 
clang-tidy---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "UseAnyOfAllOfCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Analysis/Analyses/ExprMutationAnalyzer.h"
+#include "clang/Frontend/CompilerInstance.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace {
+/// Matches a Stmt whose parent is a CompoundStmt, and which is directly
+/// followed by a Stmt matching the inner matcher.
+AST_MATCHER_P(Stmt, nextStmt, ast_matchers::internal::Matcher,
+  InnerMatcher) {
+  DynTypedNodeList Parents = Finder->getASTContext().getParents(Node);
+  if (Parents.size() != 1)
+return false;
+
+  auto *C = Parents[0].get();
+  if (!C)
+return false;
+
+  const auto *I = llvm::find(C->body(), &Node);
+  assert(I != C->body_end() && "C is parent of Node");
+  if (++I == C->body_end())
+return false; // Node is last statement.
+
+  return InnerMatcher.matches(**I, Finder, Builder);
+}
+} // namespace
+
+namespace tidy {
+namespace readability {
+
+void UseAnyOfAllOfCheck::registerMatchers(MatchFinder *Finder) {
+  auto returns = [](bool V) {
+return returnStmt(hasReturnValue(cxxBoolLiteral(equals(V;
+  };
+
+  auto returnsButNotTrue =
+  returnStmt(hasReturnValue(unless(cxxBoolLiteral(equals(true);
+  auto returnsButNotFalse =
+  returnStmt(hasReturnValue(unless(cxxBoolLiteral(equals(false);
+
+  Finder->addMatcher(
+  cxxForRangeStmt(
+  nextStmt(returns(false).bind("final_return")),
+

[clang-tools-extra] r364106 - [clang-tidy] misc-unused-parameters: don't comment out parameter name for C code

2019-06-21 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Fri Jun 21 14:30:25 2019
New Revision: 364106

URL: http://llvm.org/viewvc/llvm-project?rev=364106&view=rev
Log:
[clang-tidy] misc-unused-parameters: don't comment out parameter name for C code

Summary: The fixit `int square(int /*num*/)` yields `error: parameter name 
omitted` for C code. Enable it only for C++ code.

Reviewers: klimek, ilya-biryukov, lebedev.ri, aaron.ballman

Subscribers: xazax.hun, cfe-commits

Tags: #clang

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

Modified:
clang-tools-extra/trunk/clang-tidy/misc/UnusedParametersCheck.cpp
clang-tools-extra/trunk/test/clang-tidy/misc-unused-parameters.c

Modified: clang-tools-extra/trunk/clang-tidy/misc/UnusedParametersCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/UnusedParametersCheck.cpp?rev=364106&r1=364105&r2=364106&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/misc/UnusedParametersCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/UnusedParametersCheck.cpp Fri Jun 
21 14:30:25 2019
@@ -138,14 +138,19 @@ void UnusedParametersCheck::warnOnUnused
 Indexer = llvm::make_unique(*Result.Context);
   }
 
-  // Comment out parameter name for non-local functions.
+  // Cannot remove parameter for non-local functions.
   if (Function->isExternallyVisible() ||
   !Result.SourceManager->isInMainFile(Function->getLocation()) ||
   !Indexer->getOtherRefs(Function).empty() || isOverrideMethod(Function)) {
+
+// It is illegal to omit parameter name here in C code, so early-out.
+if (!Result.Context->getLangOpts().CPlusPlus)
+  return;
+
 SourceRange RemovalRange(Param->getLocation());
-// Note: We always add a space before the '/*' to not accidentally create a
-// '*/*' for pointer types, which doesn't start a comment. clang-format 
will
-// clean this up afterwards.
+// Note: We always add a space before the '/*' to not accidentally create
+// a '*/*' for pointer types, which doesn't start a comment. clang-format
+// will clean this up afterwards.
 MyDiag << FixItHint::CreateReplacement(
 RemovalRange, (Twine(" /*") + Param->getName() + "*/").str());
 return;

Modified: clang-tools-extra/trunk/test/clang-tidy/misc-unused-parameters.c
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-unused-parameters.c?rev=364106&r1=364105&r2=364106&view=diff
==
--- clang-tools-extra/trunk/test/clang-tidy/misc-unused-parameters.c (original)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-unused-parameters.c Fri Jun 21 
14:30:25 2019
@@ -4,7 +4,7 @@
 // =
 void a(int i) {;}
 // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused 
[misc-unused-parameters]
-// CHECK-FIXES: {{^}}void a(int  /*i*/) {;}{{$}}
+// CHECK-FIXES: {{^}}void a(int i) {;}{{$}}
 
 static void b(); // In C, forward declarations can leave out parameters.
 static void b(int i) {;}


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


[clang-tools-extra] 24130d6 - [clang-tidy] Add readability-make-member-function-const

2019-11-06 Thread Matthias Gehre via cfe-commits

Author: Matthias Gehre
Date: 2019-11-06T09:27:02+01:00
New Revision: 24130d661ed42c30f009b695d3c9ce57d2208b5e

URL: 
https://github.com/llvm/llvm-project/commit/24130d661ed42c30f009b695d3c9ce57d2208b5e
DIFF: 
https://github.com/llvm/llvm-project/commit/24130d661ed42c30f009b695d3c9ce57d2208b5e.diff

LOG: [clang-tidy] Add readability-make-member-function-const

Summary:
Finds non-static member functions that can be made ``const``
because the functions don't use ``this`` in a non-const way.

The check conservatively tries to preserve logical costness in favor of
physical costness. See readability-make-member-function-const.rst for more
details.

Reviewers: aaron.ballman, gribozavr, hokein, alexfh

Subscribers: mgorny, xazax.hun, cfe-commits

Tags: #clang

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

Added: 
clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.h

clang-tools-extra/docs/clang-tidy/checks/readability-make-member-function-const.rst
clang-tools-extra/test/clang-tidy/readability-make-member-function-const.cpp

Modified: 
clang-tools-extra/clang-tidy/readability/CMakeLists.txt
clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 7455e10831ce..bac7164508cf 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -15,6 +15,7 @@ add_clang_library(clangTidyReadabilityModule
   InconsistentDeclarationParameterNameCheck.cpp
   IsolateDeclarationCheck.cpp
   MagicNumbersCheck.cpp
+  MakeMemberFunctionConstCheck.cpp
   MisleadingIndentationCheck.cpp
   MisplacedArrayIndexCheck.cpp
   NamedParameterCheck.cpp

diff  --git 
a/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
new file mode 100644
index ..aca8d0fe89d8
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/MakeMemberFunctionConstCheck.cpp
@@ -0,0 +1,264 @@
+//===--- MakeMemberFunctionConstCheck.cpp - clang-tidy 
===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "MakeMemberFunctionConstCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); }
+
+AST_MATCHER(CXXMethodDecl, hasTrivialBody) { return Node.hasTrivialBody(); }
+
+AST_MATCHER(CXXRecordDecl, hasAnyDependentBases) {
+  return Node.hasAnyDependentBases();
+}
+
+AST_MATCHER(CXXMethodDecl, isTemplate) {
+  return Node.getTemplatedKind() != FunctionDecl::TK_NonTemplate;
+}
+
+AST_MATCHER(CXXMethodDecl, isDependentContext) {
+  return Node.isDependentContext();
+}
+
+AST_MATCHER(CXXMethodDecl, isInsideMacroDefinition) {
+  const ASTContext &Ctxt = Finder->getASTContext();
+  return clang::Lexer::makeFileCharRange(
+ clang::CharSourceRange::getCharRange(
+ Node.getTypeSourceInfo()->getTypeLoc().getSourceRange()),
+ Ctxt.getSourceManager(), Ctxt.getLangOpts())
+  .isInvalid();
+}
+
+AST_MATCHER_P(CXXMethodDecl, hasCanonicalDecl,
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  return InnerMatcher.matches(*Node.getCanonicalDecl(), Finder, Builder);
+}
+
+enum UsageKind { Unused, Const, NonConst };
+
+class FindUsageOfThis : public RecursiveASTVisitor {
+  ASTContext &Ctxt;
+
+public:
+  FindUsageOfThis(ASTContext &Ctxt) : Ctxt(Ctxt) {}
+  UsageKind Usage = Unused;
+
+  template  const T *getParent(const Expr *E) {
+ASTContext::DynTypedNodeList Parents = Ctxt.getParents(*E);
+if (Parents.size() != 1)
+  return nullptr;
+
+return Parents.begin()->get();
+  }
+
+  bool VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *) {
+// An UnresolvedMemberExpr might resolve to a non-const non-static
+// member function.
+Usage = NonConst;
+return false; // Stop traversal.
+  }
+
+  bool VisitCXXConstCastExpr(const CXXConstCastExpr *) {
+// Workaround to support the pattern
+// class C {
+//   const S *get() const;
+//   S* get() {
+// return const_cast(const_cast(this)->get());
+//   }
+// };
+// Here,

r298126 - Implement DR 373 "Lookup on namespace qualified name in using-directive"

2017-03-17 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Fri Mar 17 16:41:20 2017
New Revision: 298126

URL: http://llvm.org/viewvc/llvm-project?rev=298126&view=rev
Log:
Implement DR 373 "Lookup on namespace qualified name in using-directive"

Summary:
3.4.6 [basic.lookup.udir] paragraph 1:
In a using-directive or namespace-alias-definition, during the lookup for a 
namespace-name or for a name in a nested-name-specifier, only namespace names 
are considered.

Reviewers: rsmith, aaron.ballman

Subscribers: cfe-commits

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

Modified:
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Parse/ParseExprCXX.cpp
cfe/trunk/lib/Sema/SemaCXXScopeSpec.cpp
cfe/trunk/test/CXX/drs/dr3xx.cpp
cfe/trunk/www/cxx_dr_status.html

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=298126&r1=298125&r2=298126&view=diff
==
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri Mar 17 16:41:20 2017
@@ -1534,7 +1534,8 @@ private:
   bool EnteringContext,
   bool *MayBePseudoDestructor = nullptr,
   bool IsTypename = false,
-  IdentifierInfo **LastII = nullptr);
+  IdentifierInfo **LastII = nullptr,
+  bool OnlyNamespace = false);
 
   
//======//
   // C++0x 5.1.2: Lambda expressions

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=298126&r1=298125&r2=298126&view=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Mar 17 16:41:20 2017
@@ -5140,7 +5140,8 @@ public:
CXXScopeSpec &SS,
NamedDecl *ScopeLookupResult,
bool ErrorRecoveryLookup,
-   bool *IsCorrectedToColon = nullptr);
+   bool *IsCorrectedToColon = nullptr,
+   bool OnlyNamespace = false);
 
   /// \brief The parser has parsed a nested-name-specifier 'identifier::'.
   ///
@@ -5164,13 +5165,16 @@ public:
   /// are allowed.  The bool value pointed by this parameter is set to 'true'
   /// if the identifier is treated as if it was followed by ':', not '::'.
   ///
+  /// \param OnlyNamespace If true, only considers namespaces in lookup.
+  ///
   /// \returns true if an error occurred, false otherwise.
   bool ActOnCXXNestedNameSpecifier(Scope *S,
NestedNameSpecInfo &IdInfo,
bool EnteringContext,
CXXScopeSpec &SS,
bool ErrorRecoveryLookup = false,
-   bool *IsCorrectedToColon = nullptr);
+   bool *IsCorrectedToColon = nullptr,
+   bool OnlyNamespace = false);
 
   ExprResult ActOnDecltypeExpression(Expr *E);
 

Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=298126&r1=298125&r2=298126&view=diff
==
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Fri Mar 17 16:41:20 2017
@@ -266,15 +266,26 @@ Decl *Parser::ParseNamespaceAlias(Source
 
   CXXScopeSpec SS;
   // Parse (optional) nested-name-specifier.
-  ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false);
+  ParseOptionalCXXScopeSpecifier(SS, nullptr, /*EnteringContext=*/false,
+ /*MayBePseudoDestructor=*/nullptr,
+ /*IsTypename=*/false,
+ /*LastII=*/nullptr,
+ /*OnlyNamespace=*/true);
 
-  if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
+  if (Tok.isNot(tok::identifier)) {
 Diag(Tok, diag::err_expected_namespace_name);
 // Skip to end of the definition and eat the ';'.
 SkipUntil(tok::semi);
 return nullptr;
   }
 
+  if (SS.isInvalid()) {
+// Diagnostics have been emitted in ParseOptionalCXXScopeSpecifier.
+// Skip to end of the definition and eat the ';'.
+SkipUntil(tok::semi);
+return nullptr;
+  }
+
   // Parse identifier.
   IdentifierInfo *Ident = Tok.getIdentifierInfo();
   SourceLocation IdentLoc = Consum

r298880 - Add [[clang::suppress(rule, ...)]] attribute

2017-03-27 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Mon Mar 27 14:45:24 2017
New Revision: 298880

URL: http://llvm.org/viewvc/llvm-project?rev=298880&view=rev
Log:
Add [[clang::suppress(rule, ...)]] attribute

Summary:
This patch implements parsing of [[clang::suppress(rule, ...)]]
and [[gsl::suppress(rule, ...)]] attributes.

C++ Core Guidelines depend heavily on tool support for
rule enforcement. They also propose a way to suppress
warnings [1] which is by annotating any ancestor in AST
with the C++11 attribute [[gsl::suppress(rule1,...)]].
To have a mechanism to suppress non-C++ Core
Guidelines specific, an additional spelling of [[clang::suppress]]
is defined.

For example, to suppress the warning cppcoreguidelines-slicing,
one could do
```
[[clang::suppress("cppcoreguidelines-slicing")]]
void f() { ... code that does slicing ... }
```
or
```
void g() {
  Derived b;
  [[clang::suppress("cppcoreguidelines-slicing")]]
  Base a{b};
  [[clang::suppress("cppcoreguidelines-slicing")]] {
doSomething();
Base a2{b};
  }
}
```

This parsing can then be used by clang-tidy, which includes multiple
C++ Core Guidelines rules, to suppress warnings (see
https://reviews.llvm.org/D24888).
For the exact naming of the rule in the attribute, there
are different possibilities, which will be defined in the
corresponding clang-tidy patch.

Currently, clang-tidy supports suppressing of warnings through "//
NOLINT" comments. There are some advantages that the attribute has:
- Suppressing specific warnings instead of all warnings
- Suppressing warnings in a block (namespace, function, compound
  statement)
- Code formatting may split a statement into multiple lines,
  thus a "// NOLINT" comment may be on the wrong line

I'm looking forward to your comments!

[1] 
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#inforce-enforcement

Reviewers: alexfh, aaron.ballman, rsmith

Subscribers: cfe-commits

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

Added:
cfe/trunk/test/SemaCXX/suppress.cpp
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/AttrDocs.td
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaStmtAttr.cpp
cfe/trunk/test/Misc/ast-dump-attr.cpp

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=298880&r1=298879&r2=298880&view=diff
==
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Mon Mar 27 14:45:24 2017
@@ -1545,6 +1545,12 @@ def SwiftIndirectResult : ParameterABIAt
   let Documentation = [SwiftIndirectResultDocs];
 }
 
+def Suppress : StmtAttr {
+  let Spellings = [CXX11<"gsl", "suppress">];
+  let Args = [VariadicStringArgument<"DiagnosticIdentifiers">];
+  let Documentation = [SuppressDocs];
+}
+
 def SysVABI : InheritableAttr {
   let Spellings = [GCC<"sysv_abi">];
 //  let Subjects = [Function, ObjCMethod];

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=298880&r1=298879&r2=298880&view=diff
==
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Mon Mar 27 14:45:24 2017
@@ -2771,6 +2771,32 @@ optimizations like C++'s named return va
   }];
 }
 
+def SuppressDocs : Documentation {
+  let Category = DocCatStmt;
+  let Content = [{
+The ``[[gsl::suppress]]`` attribute suppresses specific
+clang-tidy diagnostics for rules of the `C++ Core Guidelines`_ in a portable
+way. The attribute can be attached to declarations, statements, and at
+namespace scope.
+
+.. code-block:: c++
+
+  [[gsl::suppress("Rh-public")]]
+  void f_() {
+int *p;
+[[gsl::suppress("type")]] {
+  p = reinterpret_cast(7);
+}
+  }
+  namespace N {
+[[clang::suppress("type", "bounds")]];
+...
+  }
+
+.. _`C++ Core Guidelines`: 
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#inforce-enforcement
+  }];
+}
+
 def AbiTagsDocs : Documentation {
   let Category = DocCatFunction;
   let Content = [{

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=298880&r1=298879&r2=298880&view=diff
==
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Mon Mar 27 14:45:24 2017
@@ -4097,6 +4097,26 @@ static void handleCallConvAttr(Sema &S,
   }
 }
 
+static void handleSuppressAttr(Sema &S, Decl *D, const AttributeList &Attr) {
+  if (!checkAttributeAtLeastNumArgs(S, Attr, 1))
+return;
+
+  std::vector DiagnosticIdentifiers;
+  for (unsigned I = 0, E = Attr.getNumArgs(); I != E; ++I) {
+StringRef RuleName;
+
+if (!S.checkStringLiteral

r367040 - Add lifetime categories attributes

2019-07-25 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Thu Jul 25 10:50:51 2019
New Revision: 367040

URL: http://llvm.org/viewvc/llvm-project?rev=367040&view=rev
Log:
Add lifetime categories attributes

Summary:
This is the first part of work announced in
"[RFC] Adding lifetime analysis to clang" [0],
i.e. the addition of the [[gsl::Owner(T)]] and
[[gsl::Pointer(T)]] attributes, which
will enable user-defined types to participate in
the lifetime analysis (which will be part of the
next PR).
The type `T` here is called "DerefType" in the paper,
and denotes the type that an Owner owns and a Pointer
points to. E.g. `std::vector` should be annotated
with `[[gsl::Owner(int)]]` and
a `std::vector::iterator` with `[[gsl::Pointer(int)]]`.

[0] http://lists.llvm.org/pipermail/cfe-dev/2018-November/060355.html

Reviewers: gribozavr

Subscribers: xazax.hun, cfe-commits

Tags: #clang

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

Added:
cfe/trunk/test/SemaCXX/attr-gsl-owner-pointer.cpp
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/Basic/AttrDocs.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/test/AST/ast-dump-attr.cpp
cfe/trunk/test/Misc/pragma-attribute-supported-attributes-list.test
cfe/trunk/test/SemaOpenCL/invalid-kernel-attrs.cl
cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp

Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=367040&r1=367039&r2=367040&view=diff
==
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Thu Jul 25 10:50:51 2019
@@ -2796,6 +2796,20 @@ def TypeTagForDatatype : InheritableAttr
   let Documentation = [TypeTagForDatatypeDocs];
 }
 
+def Owner : InheritableAttr {
+  let Spellings = [CXX11<"gsl", "Owner">];
+  let Subjects = SubjectList<[Struct]>;
+  let Args = [TypeArgument<"DerefType", /*opt=*/1>];
+  let Documentation = [LifetimeOwnerDocs];
+}
+
+def Pointer : InheritableAttr {
+  let Spellings = [CXX11<"gsl", "Pointer">];
+  let Subjects = SubjectList<[Struct]>;
+  let Args = [TypeArgument<"DerefType", /*opt=*/1>];
+  let Documentation = [LifetimePointerDocs];
+}
+
 // Microsoft-related attributes
 
 def MSNoVTable : InheritableAttr, TargetSpecificAttr {

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=367040&r1=367039&r2=367040&view=diff
==
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Thu Jul 25 10:50:51 2019
@@ -4230,3 +4230,71 @@ not initialized on device side. It has i
 the initializer on host side.
   }];
 }
+
+def LifetimeOwnerDocs : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+.. Note:: This attribute is experimental and its effect on analysis is subject 
to change in
+  a future version of clang.
+
+The attribute ``[[gsl::Owner(T)]]`` applies to structs and classes that own an
+object of type ``T``:
+
+.. code-block:: c++
+
+  class [[gsl::Owner(int)]] IntOwner {
+  private:
+int value;
+  public:
+int *getInt() { return &value; }
+  };
+
+The argument ``T`` is optional and currently ignored.
+This attribute may be used by analysis tools and has no effect on code
+generation.
+
+See Pointer_ for an example.
+}];
+}
+
+def LifetimePointerDocs : Documentation {
+  let Category = DocCatDecl;
+  let Content = [{
+.. Note:: This attribute is experimental and its effect on analysis is subject 
to change in
+  a future version of clang.
+
+The attribute ``[[gsl::Pointer(T)]]`` applies to structs and classes that 
behave
+like pointers to an object of type ``T``:
+
+.. code-block:: c++
+
+  class [[gsl::Pointer(int)]] IntPointer {
+  private:
+int *valuePointer;
+  public:
+int *getInt() { return &valuePointer; }
+  };
+
+The argument ``T`` is optional and currently ignored.
+This attribute may be used by analysis tools and has no effect on code
+generation.
+
+Example:
+When constructing an instance of a class annotated like this (a Pointer) from
+an instance of a class annotated with ``[[gsl::Owner]]`` (an Owner),
+then the analysis will consider the Pointer to point inside the Owner.
+When the Owner's lifetime ends, it will consider the Pointer to be dangling.
+
+.. code-block:: c++
+
+  int f() {
+IntPointer P;
+if (true) {
+  IntOwner O(7);
+  P = IntPointer(O); // P "points into" O
+} // P is dangling
+return P.get(); // error: Using a dangling Pointer.
+  }
+
+}];
+}

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=367040&r1=367039&r2=367040&view=diff
=

r368147 - gsl::Owner/gsl::Pointer: Add implicit annotations for some std types

2019-08-07 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Wed Aug  7 03:45:36 2019
New Revision: 368147

URL: http://llvm.org/viewvc/llvm-project?rev=368147&view=rev
Log:
gsl::Owner/gsl::Pointer: Add implicit annotations for some std types

Summary:
Hard code gsl::Owner/gsl::Pointer for std types. The paper mentions
some types explicitly. Generally, all containers and their iterators are
covered. For iterators, we cover both the case that they are defined
as an nested class or as an typedef/using. I have started to test this
implementation against some real standard library implementations, namely
libc++ 7.1.0, libc++ 8.0.1rc2, libstdc++ 4.6.4, libstdc++ 4.8.5,
libstdc++ 4.9.4, libstdc++ 5.4.0, libstdc++ 6.5.0, libstdc++ 7.3.0,
libstdc++ 8.3.0 and libstdc++ 9.1.0.

The tests are currently here
  https://github.com/mgehre/llvm-project/blob/lifetime-ci/lifetime-attr-test.sh
  https://github.com/mgehre/llvm-project/blob/lifetime-ci/lifetime-attr-test.cpp
I think due to their dependency on a standard library, they are not a good fit
for clang/test/. Where else could I put them?

Reviewers: gribozavr, xazax.hun

Subscribers: rnkovacs, cfe-commits

Tags: #clang

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

Added:
cfe/trunk/test/SemaCXX/attr-gsl-owner-pointer-std.cpp
Modified:
cfe/trunk/include/clang/Basic/AttrDocs.td
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaAttr.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp

Modified: cfe/trunk/include/clang/Basic/AttrDocs.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/AttrDocs.td?rev=368147&r1=368146&r2=368147&view=diff
==
--- cfe/trunk/include/clang/Basic/AttrDocs.td (original)
+++ cfe/trunk/include/clang/Basic/AttrDocs.td Wed Aug  7 03:45:36 2019
@@ -4249,7 +4249,7 @@ object of type ``T``:
 int *getInt() { return &value; }
   };
 
-The argument ``T`` is optional and currently ignored.
+The argument ``T`` is optional and is ignored.
 This attribute may be used by analysis tools and has no effect on code
 generation.
 
@@ -4275,7 +4275,7 @@ like pointers to an object of type ``T``
 int *getInt() { return &valuePointer; }
   };
 
-The argument ``T`` is optional and currently ignored.
+The argument ``T`` is optional and is ignored.
 This attribute may be used by analysis tools and has no effect on code
 generation.
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=368147&r1=368146&r2=368147&view=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Aug  7 03:45:36 2019
@@ -6116,6 +6116,17 @@ public:
   ClassTemplateSpecializationDecl *BaseTemplateSpec,
   SourceLocation BaseLoc);
 
+  /// Add gsl::Pointer attribute to std::container::iterator
+  /// \param ND The declaration that introduces the name
+  /// std::container::iterator. \param UnderlyingRecord The record named by ND.
+  void inferGslPointerAttribute(NamedDecl *ND, CXXRecordDecl 
*UnderlyingRecord);
+
+  /// Add [[gsl::Owner]] and [[gsl::Pointer]] attributes for std:: types.
+  void inferGslOwnerPointerAttribute(CXXRecordDecl *Record);
+
+  /// Add [[gsl::Pointer]] attributes for std:: types.
+  void inferGslPointerAttribute(TypedefNameDecl *TD);
+
   void CheckCompletedCXXClass(CXXRecordDecl *Record);
 
   /// Check that the C++ class annoated with "trivial_abi" satisfies all the

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=368147&r1=368146&r2=368147&view=diff
==
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Wed Aug  7 03:45:36 2019
@@ -85,6 +85,126 @@ void Sema::AddMsStructLayoutForRecord(Re
 MSVtorDispAttr::CreateImplicit(Context, VtorDispStack.CurrentValue));
 }
 
+template 
+static void addGslOwnerPointerAttributeIfNotExisting(ASTContext &Context,
+ CXXRecordDecl *Record) {
+  CXXRecordDecl *Canonical = Record->getCanonicalDecl();
+  if (Canonical->hasAttr() || Canonical->hasAttr())
+return;
+
+  Canonical->addAttr(::new (Context) Attribute(SourceRange{}, Context,
+   /*DerefType*/ nullptr,
+   /*Spelling=*/0));
+}
+
+void Sema::inferGslPointerAttribute(NamedDecl *ND,
+CXXRecordDecl *UnderlyingRecord) {
+  if (!UnderlyingRecord)
+return;
+
+  const auto *Parent = dyn_cast(ND->getDeclContext());
+  if (!Parent)
+return;
+
+  static llvm::StringSet<> Containers{
+  "array",
+  "basic_string",
+  "deque",
+  "forward_list",
+  "vector",
+  "list",
+  

[clang-tools-extra] r361601 - [clang-tidy] Add option "LiteralInitializers" to cppcoreguidelines-pro-type-member-init

2019-05-23 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Thu May 23 22:46:57 2019
New Revision: 361601

URL: http://llvm.org/viewvc/llvm-project?rev=361601&view=rev
Log:
[clang-tidy] Add option "LiteralInitializers" to 
cppcoreguidelines-pro-type-member-init

Differential Revision: D24892

Added:

clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-type-member-init-use-assignment.cpp
Modified:

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h
clang-tools-extra/trunk/docs/ReleaseNotes.rst

clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-pro-type-member-init.rst

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp?rev=361601&r1=361600&r2=361601&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp 
(original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp 
Thu May 23 22:46:57 2019
@@ -250,7 +250,8 @@ void fixInitializerList(const ASTContext
 ProTypeMemberInitCheck::ProTypeMemberInitCheck(StringRef Name,
ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
-  IgnoreArrays(Options.get("IgnoreArrays", false)) {}
+  IgnoreArrays(Options.get("IgnoreArrays", false)),
+  UseAssignment(Options.getLocalOrGlobal("UseAssignment", false)) {}
 
 void ProTypeMemberInitCheck::registerMatchers(MatchFinder *Finder) {
   if (!getLangOpts().CPlusPlus)
@@ -314,6 +315,7 @@ void ProTypeMemberInitCheck::check(const
 
 void ProTypeMemberInitCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
   Options.store(Opts, "IgnoreArrays", IgnoreArrays);
+  Options.store(Opts, "UseAssignment", UseAssignment);
 }
 
 // FIXME: Copied from clang/lib/Sema/SemaDeclCXX.cpp.
@@ -338,6 +340,56 @@ static bool isEmpty(ASTContext &Context,
   return isIncompleteOrZeroLengthArrayType(Context, Type);
 }
 
+static const char *getInitializer(QualType QT, bool UseAssignment) {
+  const char *DefaultInitializer = "{}";
+  if (!UseAssignment)
+return DefaultInitializer;
+
+  if (QT->isPointerType())
+return " = nullptr";
+
+  const BuiltinType *BT =
+  dyn_cast(QT.getCanonicalType().getTypePtr());
+  if (!BT)
+return DefaultInitializer;
+
+  switch (BT->getKind()) {
+  case BuiltinType::Bool:
+return " = false";
+  case BuiltinType::Float:
+return " = 0.0F";
+  case BuiltinType::Double:
+return " = 0.0";
+  case BuiltinType::LongDouble:
+return " = 0.0L";
+  case BuiltinType::SChar:
+  case BuiltinType::Char_S:
+  case BuiltinType::WChar_S:
+  case BuiltinType::Char16:
+  case BuiltinType::Char32:
+  case BuiltinType::Short:
+  case BuiltinType::Int:
+return " = 0";
+  case BuiltinType::UChar:
+  case BuiltinType::Char_U:
+  case BuiltinType::WChar_U:
+  case BuiltinType::UShort:
+  case BuiltinType::UInt:
+return " = 0U";
+  case BuiltinType::Long:
+return " = 0L";
+  case BuiltinType::ULong:
+return " = 0UL";
+  case BuiltinType::LongLong:
+return " = 0LL";
+  case BuiltinType::ULongLong:
+return " = 0ULL";
+
+  default:
+return DefaultInitializer;
+  }
+}
+
 void ProTypeMemberInitCheck::checkMissingMemberInitializer(
 ASTContext &Context, const CXXRecordDecl &ClassDecl,
 const CXXConstructorDecl *Ctor) {
@@ -420,7 +472,7 @@ void ProTypeMemberInitCheck::checkMissin
 for (const FieldDecl *Field : FieldsToFix) {
   Diag << FixItHint::CreateInsertion(
   getLocationForEndOfToken(Context, Field->getSourceRange().getEnd()),
-  "{}");
+  getInitializer(Field->getType(), UseAssignment));
 }
   } else if (Ctor) {
 // Otherwise, rewrite the constructor's initializer list.

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h?rev=361601&r1=361600&r2=361601&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h 
(original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h 
Thu May 23 22:46:57 2019
@@ -64,6 +64,11 @@ private:
 
   // Whether arrays need to be initialized or not. Default is false.
   bool IgnoreArrays;
+
+  // Whether fix-its for initialization of fundamental type use assignment
+  // instead of brace initalization. Only effective in C++11 mode. Default is
+  // false.
+  bool UseAssignment;
 };
 
 } // namespace cppcoreguidelines

Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-

[clang-tools-extra] r360613 - [clang-tidy] readability-redundant-declaration: fix false positive with C "extern inline"

2019-05-13 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Mon May 13 12:21:57 2019
New Revision: 360613

URL: http://llvm.org/viewvc/llvm-project?rev=360613&view=rev
Log:
[clang-tidy] readability-redundant-declaration: fix false positive with C 
"extern inline"

Summary:
readability-redundant-declaration was diagnosing a redundant declaration
on "extern inline void f();", which is needed in C code to force an external 
definition
of the inline function f. (This is different to how inline behaves in C++).

Reviewers: alexfh, danielmarjamaki

Subscribers: xazax.hun, cfe-commits

Tags: #clang

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

Added:
clang-tools-extra/trunk/test/clang-tidy/readability-redundant-declaration.c
Modified:
clang-tools-extra/trunk/clang-tidy/readability/RedundantDeclarationCheck.cpp

clang-tools-extra/trunk/test/clang-tidy/readability-redundant-declaration.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/readability/RedundantDeclarationCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/RedundantDeclarationCheck.cpp?rev=360613&r1=360612&r2=360613&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/readability/RedundantDeclarationCheck.cpp 
(original)
+++ 
clang-tools-extra/trunk/clang-tidy/readability/RedundantDeclarationCheck.cpp 
Mon May 13 12:21:57 2019
@@ -17,6 +17,10 @@ namespace clang {
 namespace tidy {
 namespace readability {
 
+AST_MATCHER(FunctionDecl, doesDeclarationForceExternallyVisibleDefinition) {
+  return Node.doesDeclarationForceExternallyVisibleDefinition();
+}
+
 RedundantDeclarationCheck::RedundantDeclarationCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
@@ -25,8 +29,10 @@ RedundantDeclarationCheck::RedundantDecl
 void RedundantDeclarationCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
   namedDecl(anyOf(varDecl(unless(isDefinition())),
-  functionDecl(unless(anyOf(isDefinition(), isDefaulted(),
-hasParent(friendDecl()))
+  functionDecl(unless(anyOf(
+  isDefinition(), isDefaulted(),
+  doesDeclarationForceExternallyVisibleDefinition(),
+  hasParent(friendDecl()))
   .bind("Decl"),
   this);
 }

Added: 
clang-tools-extra/trunk/test/clang-tidy/readability-redundant-declaration.c
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-redundant-declaration.c?rev=360613&view=auto
==
--- clang-tools-extra/trunk/test/clang-tidy/readability-redundant-declaration.c 
(added)
+++ clang-tools-extra/trunk/test/clang-tidy/readability-redundant-declaration.c 
Mon May 13 12:21:57 2019
@@ -0,0 +1,31 @@
+// RUN: %check_clang_tidy %s readability-redundant-declaration %t
+
+extern int Xyz;
+extern int Xyz; // Xyz
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'Xyz' declaration 
[readability-redundant-declaration]
+// CHECK-FIXES: {{^}}// Xyz{{$}}
+int Xyz = 123;
+
+extern int A;
+extern int A, B;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'A' declaration
+// CHECK-FIXES: {{^}}extern int A, B;{{$}}
+
+extern int Buf[10];
+extern int Buf[10]; // Buf[10]
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'Buf' declaration
+// CHECK-FIXES: {{^}}// Buf[10]{{$}}
+
+static int f();
+static int f(); // f
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant 'f' declaration
+// CHECK-FIXES: {{^}}// f{{$}}
+static int f() {}
+
+inline void g() {}
+
+inline void g();
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant 'g' declaration
+
+// OK: Needed to emit an external definition.
+extern inline void g();

Modified: 
clang-tools-extra/trunk/test/clang-tidy/readability-redundant-declaration.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-redundant-declaration.cpp?rev=360613&r1=360612&r2=360613&view=diff
==
--- 
clang-tools-extra/trunk/test/clang-tidy/readability-redundant-declaration.cpp 
(original)
+++ 
clang-tools-extra/trunk/test/clang-tidy/readability-redundant-declaration.cpp 
Mon May 13 12:21:57 2019
@@ -68,3 +68,13 @@ DEFINE(test);
 // CHECK-FIXES: {{^}}DEFINE(test);{{$}}
 
 } // namespace macros
+
+inline void g() {}
+
+inline void g(); // g
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant 'g' declaration
+// CHECK-FIXES: {{^}}// g{{$}}
+
+extern inline void g(); // extern g
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant 'g' declaration
+// CHECK-FIXES: {{^}}// extern g{{$}}


___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/c

[clang-tools-extra] r360698 - [clang-tidy] Fix invalid fixit for readability-static-accessed-through-instance (bug 40544)

2019-05-14 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Tue May 14 11:23:10 2019
New Revision: 360698

URL: http://llvm.org/viewvc/llvm-project?rev=360698&view=rev
Log:
[clang-tidy] Fix invalid fixit for readability-static-accessed-through-instance 
(bug 40544)

Summary:
Fixed https://bugs.llvm.org/show_bug.cgi?id=40544
Before, we would generate a fixit like `(anonymous namespace)::Foo::fun();` for
the added test case.

Reviewers: aaron.ballman, alexfh, xazax.hun

Subscribers: rnkovacs, cfe-commits

Tags: #clang, #clang-tools-extra

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

Modified:

clang-tools-extra/trunk/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp

clang-tools-extra/trunk/test/clang-tidy/readability-static-accessed-through-instance.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp?rev=360698&r1=360697&r2=360698&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
 Tue May 14 11:23:10 2019
@@ -67,6 +67,7 @@ void StaticAccessedThroughInstanceCheck:
   const ASTContext *AstContext = Result.Context;
   PrintingPolicy PrintingPolicyWithSupressedTag(AstContext->getLangOpts());
   PrintingPolicyWithSupressedTag.SuppressTagKeyword = true;
+  PrintingPolicyWithSupressedTag.SuppressUnwrittenScope = true;
   std::string BaseTypeName =
   BaseType.getAsString(PrintingPolicyWithSupressedTag);
 

Modified: 
clang-tools-extra/trunk/test/clang-tidy/readability-static-accessed-through-instance.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-static-accessed-through-instance.cpp?rev=360698&r1=360697&r2=360698&view=diff
==
--- 
clang-tools-extra/trunk/test/clang-tidy/readability-static-accessed-through-instance.cpp
 (original)
+++ 
clang-tools-extra/trunk/test/clang-tidy/readability-static-accessed-through-instance.cpp
 Tue May 14 11:23:10 2019
@@ -220,3 +220,31 @@ int func(Qptr qp) {
   qp->y = 10; // OK, the overloaded operator might have side-effects.
   qp->K = 10; //
 }
+
+namespace {
+  struct Anonymous {
+static int I;
+  };
+}
+
+void use_anonymous() {
+  Anonymous Anon;
+  Anon.I;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+  // CHECK-FIXES: {{^}}  Anonymous::I;{{$}}
+}
+
+namespace Outer {
+  inline namespace Inline {
+struct S {
+  static int I;
+};
+  }
+}
+
+void use_inline() {
+  Outer::S V;
+  V.I;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: static member
+  // CHECK-FIXES: {{^}}  Outer::S::I;{{$}}
+}


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


r371182 - Reland [LifetimeAnalysis] Support more STL idioms (template forward declaration and DependentNameType)

2019-09-06 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Fri Sep  6 01:56:30 2019
New Revision: 371182

URL: http://llvm.org/viewvc/llvm-project?rev=371182&view=rev
Log:
Reland [LifetimeAnalysis] Support more STL idioms (template forward declaration 
and DependentNameType)

Reland after https://reviews.llvm.org/D66806 fixed the false-positive 
diagnostics.

Summary:
This fixes inference of gsl::Pointer on std::set::iterator with libstdc++ (the 
typedef for iterator
on the template is a DependentNameType - we can only put the gsl::Pointer 
attribute
on the underlaying record after instantiation)

inference of gsl::Pointer on std::vector::iterator with libc++ (the class was 
forward-declared,
we added the gsl::Pointer on the canonical decl (the forward decl), and later 
when the
template was instantiated, there was no attribute on the definition so it was 
not instantiated).

and a duplicate gsl::Pointer on some class with libstdc++ (we first added an 
attribute to
a incomplete instantiation, and then another was copied from the template 
definition
when the instantiation was completed).

We now add the attributes to all redeclarations to fix thos issues and make 
their usage easier.

Reviewers: gribozavr

Subscribers: Szelethus, xazax.hun, cfe-commits

Tags: #clang

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

Added:
cfe/trunk/unittests/Sema/GslOwnerPointerInference.cpp
Modified:
cfe/trunk/lib/Sema/SemaAttr.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/attr-gsl-owner-pointer-std.cpp
cfe/trunk/test/SemaCXX/attr-gsl-owner-pointer.cpp
cfe/trunk/unittests/Sema/CMakeLists.txt

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=371182&r1=371181&r2=371182&view=diff
==
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Fri Sep  6 01:56:30 2019
@@ -88,13 +88,11 @@ void Sema::AddMsStructLayoutForRecord(Re
 template 
 static void addGslOwnerPointerAttributeIfNotExisting(ASTContext &Context,
  CXXRecordDecl *Record) {
-  CXXRecordDecl *Canonical = Record->getCanonicalDecl();
-  if (Canonical->hasAttr() || Canonical->hasAttr())
+  if (Record->hasAttr() || Record->hasAttr())
 return;
 
-  Canonical->addAttr(::new (Context) Attribute(SourceRange{}, Context,
-   /*DerefType*/ nullptr,
-   /*Spelling=*/0));
+  for (Decl *Redecl : Record->redecls())
+Redecl->addAttr(Attribute::CreateImplicit(Context, /*DerefType=*/nullptr));
 }
 
 void Sema::inferGslPointerAttribute(NamedDecl *ND,
@@ -189,8 +187,7 @@ void Sema::inferGslOwnerPointerAttribute
 
   // Handle classes that directly appear in std namespace.
   if (Record->isInStdNamespace()) {
-CXXRecordDecl *Canonical = Record->getCanonicalDecl();
-if (Canonical->hasAttr() || Canonical->hasAttr())
+if (Record->hasAttr() || Record->hasAttr())
   return;
 
 if (StdOwners.count(Record->getName()))

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=371182&r1=371181&r2=371182&view=diff
==
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Sep  6 01:56:30 2019
@@ -4592,9 +4592,11 @@ static void handleLifetimeCategoryAttr(S
   }
   return;
 }
-D->addAttr(::new (S.Context)
-   OwnerAttr(AL.getRange(), S.Context, DerefTypeLoc,
- AL.getAttributeSpellingListIndex()));
+for (Decl *Redecl : D->redecls()) {
+  Redecl->addAttr(::new (S.Context)
+  OwnerAttr(AL.getRange(), S.Context, DerefTypeLoc,
+AL.getAttributeSpellingListIndex()));
+}
   } else {
 if (checkAttrMutualExclusion(S, D, AL))
   return;
@@ -4609,9 +4611,11 @@ static void handleLifetimeCategoryAttr(S
   }
   return;
 }
-D->addAttr(::new (S.Context)
-   PointerAttr(AL.getRange(), S.Context, DerefTypeLoc,
-   AL.getAttributeSpellingListIndex()));
+for (Decl *Redecl : D->redecls()) {
+  Redecl->addAttr(::new (S.Context)
+  PointerAttr(AL.getRange(), S.Context, DerefTypeLoc,
+  AL.getAttributeSpellingListIndex()));
+}
   }
 }
 

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=371182&r1=371181&r2=371182&view=diff
==
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/Se

r371241 - [LifetimeAnalysis] don't use raw string literals in macros

2019-09-06 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Fri Sep  6 12:15:02 2019
New Revision: 371241

URL: http://llvm.org/viewvc/llvm-project?rev=371241&view=rev
Log:
[LifetimeAnalysis] don't use raw string literals in macros

They broke the AArch64 bots (gcc does not support it)

Modified:
cfe/trunk/unittests/Sema/GslOwnerPointerInference.cpp

Modified: cfe/trunk/unittests/Sema/GslOwnerPointerInference.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Sema/GslOwnerPointerInference.cpp?rev=371241&r1=371240&r2=371241&view=diff
==
--- cfe/trunk/unittests/Sema/GslOwnerPointerInference.cpp (original)
+++ cfe/trunk/unittests/Sema/GslOwnerPointerInference.cpp Fri Sep  6 12:15:02 
2019
@@ -14,48 +14,42 @@ namespace clang {
 using namespace ast_matchers;
 
 TEST(OwnerPointer, BothHaveAttributes) {
-  EXPECT_TRUE(matches(
-R"cpp(
-  template
-  class [[gsl::Owner]] C;
-
-  template
-  class [[gsl::Owner]] C {};
-
-  C c;
-  )cpp",
-classTemplateSpecializationDecl(hasName("C"), 
hasAttr(clang::attr::Owner;
+  EXPECT_TRUE(matches("template"
+  "class [[gsl::Owner]] C;"
+
+  "template"
+  "class [[gsl::Owner]] C {};"
+
+  "C c;",
+  classTemplateSpecializationDecl(
+  hasName("C"), hasAttr(clang::attr::Owner;
 }
 
 TEST(OwnerPointer, ForwardDeclOnly) {
-  EXPECT_TRUE(matches(
-R"cpp(
-  template
-  class [[gsl::Owner]] C;
-
-  template
-  class C {};
-
-  C c;
-  )cpp",
-classTemplateSpecializationDecl(hasName("C"), 
hasAttr(clang::attr::Owner;
+  EXPECT_TRUE(matches("template"
+  "class [[gsl::Owner]] C;"
+
+  "template"
+  "class C {};"
+
+  "C c;",
+  classTemplateSpecializationDecl(
+  hasName("C"), hasAttr(clang::attr::Owner;
 }
 
 TEST(OwnerPointer, LateForwardDeclOnly) {
-  EXPECT_TRUE(matches(
-R"cpp(
-  template
-  class C;
-
-  template
-  class C {};
-
-  template
-  class [[gsl::Owner]] C;
-
-  C c;
-  )cpp",
-classTemplateSpecializationDecl(hasName("C"), 
hasAttr(clang::attr::Owner;
+  EXPECT_TRUE(matches("template"
+  "class C;"
+
+  "template"
+  "class C {};"
+
+  "template"
+  "class [[gsl::Owner]] C;"
+
+  "C c;",
+  classTemplateSpecializationDecl(
+  hasName("C"), hasAttr(clang::attr::Owner;
 }
 
 } // namespace clang


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


Re: r371182 - Reland [LifetimeAnalysis] Support more STL idioms (template forward declaration and DependentNameType)

2019-09-06 Thread Matthias Gehre via cfe-commits
Yvan, sorry!
Should be fixed now.

Am Fr., 6. Sept. 2019 um 16:40 Uhr schrieb Yvan Roux :

> Hi Matthias,
>
> this commit broke AArch64 bots, logs are available here:
>
>
> http://lab.llvm.org:8011/builders/clang-cmake-aarch64-quick/builds/19917/steps/ninja%20check%201/logs/stdio
>
> Thanks,
> Yvan
>
> On Fri, 6 Sep 2019 at 10:54, Matthias Gehre via cfe-commits
>  wrote:
> >
> > Author: mgehre
> > Date: Fri Sep  6 01:56:30 2019
> > New Revision: 371182
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=371182&view=rev
> > Log:
> > Reland [LifetimeAnalysis] Support more STL idioms (template forward
> declaration and DependentNameType)
> >
> > Reland after https://reviews.llvm.org/D66806 fixed the false-positive
> diagnostics.
> >
> > Summary:
> > This fixes inference of gsl::Pointer on std::set::iterator with
> libstdc++ (the typedef for iterator
> > on the template is a DependentNameType - we can only put the
> gsl::Pointer attribute
> > on the underlaying record after instantiation)
> >
> > inference of gsl::Pointer on std::vector::iterator with libc++ (the
> class was forward-declared,
> > we added the gsl::Pointer on the canonical decl (the forward decl), and
> later when the
> > template was instantiated, there was no attribute on the definition so
> it was not instantiated).
> >
> > and a duplicate gsl::Pointer on some class with libstdc++ (we first
> added an attribute to
> > a incomplete instantiation, and then another was copied from the
> template definition
> > when the instantiation was completed).
> >
> > We now add the attributes to all redeclarations to fix thos issues and
> make their usage easier.
> >
> > Reviewers: gribozavr
> >
> > Subscribers: Szelethus, xazax.hun, cfe-commits
> >
> > Tags: #clang
> >
> > Differential Revision: https://reviews.llvm.org/D66179
> >
> > Added:
> > cfe/trunk/unittests/Sema/GslOwnerPointerInference.cpp
> > Modified:
> > cfe/trunk/lib/Sema/SemaAttr.cpp
> > cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> > cfe/trunk/lib/Sema/SemaInit.cpp
> > cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> > cfe/trunk/test/SemaCXX/attr-gsl-owner-pointer-std.cpp
> > cfe/trunk/test/SemaCXX/attr-gsl-owner-pointer.cpp
> > cfe/trunk/unittests/Sema/CMakeLists.txt
> >
> > Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=371182&r1=371181&r2=371182&view=diff
> >
> ==
> > --- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaAttr.cpp Fri Sep  6 01:56:30 2019
> > @@ -88,13 +88,11 @@ void Sema::AddMsStructLayoutForRecord(Re
> >  template 
> >  static void addGslOwnerPointerAttributeIfNotExisting(ASTContext
> &Context,
> >   CXXRecordDecl
> *Record) {
> > -  CXXRecordDecl *Canonical = Record->getCanonicalDecl();
> > -  if (Canonical->hasAttr() ||
> Canonical->hasAttr())
> > +  if (Record->hasAttr() || Record->hasAttr())
> >  return;
> >
> > -  Canonical->addAttr(::new (Context) Attribute(SourceRange{}, Context,
> > -   /*DerefType*/ nullptr,
> > -   /*Spelling=*/0));
> > +  for (Decl *Redecl : Record->redecls())
> > +Redecl->addAttr(Attribute::CreateImplicit(Context,
> /*DerefType=*/nullptr));
> >  }
> >
> >  void Sema::inferGslPointerAttribute(NamedDecl *ND,
> > @@ -189,8 +187,7 @@ void Sema::inferGslOwnerPointerAttribute
> >
> >// Handle classes that directly appear in std namespace.
> >if (Record->isInStdNamespace()) {
> > -CXXRecordDecl *Canonical = Record->getCanonicalDecl();
> > -if (Canonical->hasAttr() ||
> Canonical->hasAttr())
> > +if (Record->hasAttr() || Record->hasAttr())
> >return;
> >
> >  if (StdOwners.count(Record->getName()))
> >
> > Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=371182&r1=371181&r2=371182&view=diff
> >
> ==
> > --- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
> > +++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Fri Sep  6 01:56:30 2019
> >

[clang-tools-extra] r253399 - Fix bug 25362 "cppcoreguidelines-pro-bounds-array-to-pointer-decay does not consider const"

2015-11-17 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Tue Nov 17 17:35:39 2015
New Revision: 253399

URL: http://llvm.org/viewvc/llvm-project?rev=253399&view=rev
Log:
Fix bug 25362 "cppcoreguidelines-pro-bounds-array-to-pointer-decay does not 
consider const"

Summary:
The current matcher is
  implicitCastExpr(unless(hasParent(explicitCastExpr(
but the AST in the bug is
  `-CXXStaticCastExpr 0x2bb64f8  'void *const *'
static_cast 
`-ImplicitCastExpr 0x2bb64e0  'void *const *' 
  `-ImplicitCastExpr 0x2bb64c8  'void **'

`-DeclRefExpr 0x2bb6458  'void *[2]' lvalue Var
0x2bb59d0 'addrlist' 'void *[2]'
i.e. an ImplicitCastExpr (const cast) between decay and explicit cast.

Reviewers: alexfh, sbenza, bkramer, aaron.ballman

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D14517

Modified:

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h

clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp?rev=253399&r1=253398&r2=253399&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
 Tue Nov 17 17:35:39 2015
@@ -28,6 +28,22 @@ AST_MATCHER(Stmt, isInsideOfRangeBeginEn
   .matches(Node, Finder, Builder);
 }
 
+AST_MATCHER_P(Expr, hasParentIgnoringImpCasts,
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  const Expr *E = &Node;
+  do {
+ASTContext::DynTypedNodeList Parents =
+Finder->getASTContext().getParents(*E);
+if (Parents.size() != 1)
+  return false;
+E = Parents[0].get();
+if (!E)
+  return false;
+  } while (isa(E));
+
+  return InnerMatcher.matches(*E, Finder, Builder);
+}
+
 void ProBoundsArrayToPointerDecayCheck::registerMatchers(MatchFinder *Finder) {
   if (!getLangOpts().CPlusPlus)
 return;
@@ -38,7 +54,7 @@ void ProBoundsArrayToPointerDecayCheck::
   // 3) if it converts a string literal to a pointer
   Finder->addMatcher(
   implicitCastExpr(unless(hasParent(arraySubscriptExpr())),
-   unless(hasParent(explicitCastExpr())),
+   unless(hasParentIgnoringImpCasts(explicitCastExpr())),
unless(isInsideOfRangeBeginEndStmt()),
unless(hasSourceExpression(stringLiteral(
   .bind("cast"),

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h?rev=253399&r1=253398&r2=253399&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
 Tue Nov 17 17:35:39 2015
@@ -31,4 +31,3 @@ public:
 } // namespace clang
 
 #endif // 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_ARRAY_TO_POINTER_DECAY_H
-

Modified: 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp?rev=253399&r1=253398&r2=253399&view=diff
==
--- 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
 (original)
+++ 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
 Tue Nov 17 17:35:39 2015
@@ -39,3 +39,9 @@ void f() {
 const char *g() {
   return "clang"; // OK, decay string literal to pointer
 }
+
+void f2(void *const *);
+void bug25362() {
+  void *a[2];
+  f2(static_cast(a)); // OK, explicit cast
+}


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


Re: [PATCH] D14517: Fix bug 25362 "cppcoreguidelines-pro-bounds-array-to-pointer-decay does not consider const"

2015-11-17 Thread Matthias Gehre via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL253399: Fix bug 25362 
"cppcoreguidelines-pro-bounds-array-to-pointer-decay does not… (authored by 
mgehre).

Changed prior to commit:
  http://reviews.llvm.org/D14517?vs=39948&id=40446#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D14517

Files:
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
  
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp

Index: 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
===
--- 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
+++ 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
@@ -39,3 +39,9 @@
 const char *g() {
   return "clang"; // OK, decay string literal to pointer
 }
+
+void f2(void *const *);
+void bug25362() {
+  void *a[2];
+  f2(static_cast(a)); // OK, explicit cast
+}
Index: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
===
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
@@ -31,4 +31,3 @@
 } // namespace clang
 
 #endif // 
LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_ARRAY_TO_POINTER_DECAY_H
-
Index: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
===
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
@@ -28,6 +28,22 @@
   .matches(Node, Finder, Builder);
 }
 
+AST_MATCHER_P(Expr, hasParentIgnoringImpCasts,
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  const Expr *E = &Node;
+  do {
+ASTContext::DynTypedNodeList Parents =
+Finder->getASTContext().getParents(*E);
+if (Parents.size() != 1)
+  return false;
+E = Parents[0].get();
+if (!E)
+  return false;
+  } while (isa(E));
+
+  return InnerMatcher.matches(*E, Finder, Builder);
+}
+
 void ProBoundsArrayToPointerDecayCheck::registerMatchers(MatchFinder *Finder) {
   if (!getLangOpts().CPlusPlus)
 return;
@@ -38,7 +54,7 @@
   // 3) if it converts a string literal to a pointer
   Finder->addMatcher(
   implicitCastExpr(unless(hasParent(arraySubscriptExpr())),
-   unless(hasParent(explicitCastExpr())),
+   unless(hasParentIgnoringImpCasts(explicitCastExpr())),
unless(isInsideOfRangeBeginEndStmt()),
unless(hasSourceExpression(stringLiteral(
   .bind("cast"),


Index: clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
@@ -39,3 +39,9 @@
 const char *g() {
   return "clang"; // OK, decay string literal to pointer
 }
+
+void f2(void *const *);
+void bug25362() {
+  void *a[2];
+  f2(static_cast(a)); // OK, explicit cast
+}
Index: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
===
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
@@ -31,4 +31,3 @@
 } // namespace clang
 
 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_ARRAY_TO_POINTER_DECAY_H
-
Index: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
@@ -28,6 +28,22 @@
   .matches(Node, Finder, Builder);
 }
 
+AST_MATCHER_P(Expr, hasParentIgnoringImpCasts,
+  ast_matchers::internal::Matcher, InnerMatcher) {
+  const Expr *E = &Node;
+  do {
+ASTContext::DynTypedNodeList Parents =
+Finder->getASTContext().getParents(*E);
+if (Parents.size() != 1)
+  return false;
+E = Parents[0].get();
+if (!E)
+  return false;
+  }

Re: [PATCH] D14582: [clang-tidy] cppcoreguidelines-pro-bounds-pointer-arithmetic: ignore generated pointer arithmetic

2015-11-17 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 40448.
mgehre added a comment.

Simplified with Alex suggestion. Thanks!


http://reviews.llvm.org/D14582

Files:
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
  test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===
--- test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -84,4 +84,6 @@
   i = j - 1;
 
   auto diff = p - q; // OK, result is arithmetic
+
+  for(int ii : a) ; // OK, pointer arithmetic generated by compiler
 }
Index: clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
===
--- clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
+++ clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -24,7 +24,8 @@
   Finder->addMatcher(
   binaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-"),
hasOperatorName("+="), hasOperatorName("-=")),
- hasType(pointerType()))
+ hasType(pointerType()),
+ 
unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit()))
   .bind("expr"),
   this);
 


Index: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===
--- test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -84,4 +84,6 @@
   i = j - 1;
 
   auto diff = p - q; // OK, result is arithmetic
+
+  for(int ii : a) ; // OK, pointer arithmetic generated by compiler
 }
Index: clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
===
--- clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
+++ clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -24,7 +24,8 @@
   Finder->addMatcher(
   binaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-"),
hasOperatorName("+="), hasOperatorName("-=")),
- hasType(pointerType()))
+ hasType(pointerType()),
+ unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit()))
   .bind("expr"),
   this);
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] r253401 - [clang-tidy] add check cppcoreguidelines-pro-bounds-constant-array-index

2015-11-17 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Tue Nov 17 17:43:20 2015
New Revision: 253401

URL: http://llvm.org/viewvc/llvm-project?rev=253401&view=rev
Log:
[clang-tidy] add check cppcoreguidelines-pro-bounds-constant-array-index

Summary:
This check flags all array subscriptions on static arrays and
std::arrays that either have a non-compile-time-constant index or are
out of bounds.

Dynamic accesses into arrays are difficult for both tools and humans to
validate as safe. array_view is a bounds-checked, safe type for
accessing arrays of data. at() is another alternative that ensures
single accesses are bounds-checked. If iterators are needed to access an
array, use the iterators from an array_view constructed over the array.

This rule is part of the "Bounds safety" profile of the C++ Core
Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds2-only-index-into-arrays-using-constant-expressions

Reviewers: alexfh, sbenza, bkramer, aaron.ballman

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D13746

Added:

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h

clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.rst

clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt?rev=253401&r1=253400&r2=253401&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt 
(original)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt Tue Nov 
17 17:43:20 2015
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support)
 add_clang_library(clangTidyCppCoreGuidelinesModule
   CppCoreGuidelinesTidyModule.cpp
   ProBoundsArrayToPointerDecayCheck.cpp
+  ProBoundsConstantArrayIndexCheck.cpp
   ProBoundsPointerArithmeticCheck.cpp
   ProTypeConstCastCheck.cpp
   ProTypeCstyleCastCheck.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp?rev=253401&r1=253400&r2=253401&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
 Tue Nov 17 17:43:20 2015
@@ -12,6 +12,7 @@
 #include "../ClangTidyModuleRegistry.h"
 #include "../misc/AssignOperatorSignatureCheck.h"
 #include "ProBoundsArrayToPointerDecayCheck.h"
+#include "ProBoundsConstantArrayIndexCheck.h"
 #include "ProBoundsPointerArithmeticCheck.h"
 #include "ProTypeConstCastCheck.h"
 #include "ProTypeCstyleCastCheck.h"
@@ -30,6 +31,8 @@ public:
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
 CheckFactories.registerCheck(
 "cppcoreguidelines-pro-bounds-array-to-pointer-decay");
+CheckFactories.registerCheck(
+"cppcoreguidelines-pro-bounds-constant-array-index");
 CheckFactories.registerCheck(
 "cppcoreguidelines-pro-bounds-pointer-arithmetic");
 CheckFactories.registerCheck(

Added: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp?rev=253401&view=auto
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
 (added)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
 Tue Nov 17 17:43:20 2015
@@ -0,0 +1,131 @@
+//===--- ProBoundsConstantArrayIndexCheck.cpp - 
clang-tidy-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ProBoundsConstantArrayIndexCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;

Re: [PATCH] D13746: [clang-tidy] add check cppcoreguidelines-pro-bounds-constant-array-index

2015-11-17 Thread Matthias Gehre via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL253401: [clang-tidy] add check 
cppcoreguidelines-pro-bounds-constant-array-index (authored by mgehre).

Changed prior to commit:
  http://reviews.llvm.org/D13746?vs=39953&id=40449#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D13746

Files:
  clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
  
clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.rst
  clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp

Index: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
===
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
@@ -0,0 +1,40 @@
+//===--- ProBoundsConstantArrayIndexCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_CONSTANT_ARRAY_INDEX_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_CONSTANT_ARRAY_INDEX_H
+
+#include "../ClangTidy.h"
+#include "../utils/IncludeInserter.h"
+
+namespace clang {
+namespace tidy {
+
+/// This checks that all array subscriptions on static arrays and std::arrays
+/// have a constant index and are within bounds
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.html
+class ProBoundsConstantArrayIndexCheck : public ClangTidyCheck {
+  std::string GslHeader;
+  const IncludeSorter::IncludeStyle IncludeStyle;
+  std::unique_ptr Inserter;
+
+public:
+  ProBoundsConstantArrayIndexCheck(StringRef Name, ClangTidyContext *Context);
+  void registerPPCallbacks(CompilerInstance &Compiler) override;
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_CONSTANT_ARRAY_INDEX_H
Index: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
@@ -0,0 +1,131 @@
+//===--- ProBoundsConstantArrayIndexCheck.cpp - clang-tidy-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ProBoundsConstantArrayIndexCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Frontend/CompilerInstance.h"
+#include "clang/Lex/Preprocessor.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+ProBoundsConstantArrayIndexCheck::ProBoundsConstantArrayIndexCheck(
+StringRef Name, ClangTidyContext *Context)
+: ClangTidyCheck(Name, Context), GslHeader(Options.get("GslHeader", "")),
+  IncludeStyle(IncludeSorter::parseIncludeStyle(
+  Options.get("IncludeStyle", "llvm"))) {}
+
+void ProBoundsConstantArrayIndexCheck::storeOptions(
+ClangTidyOptions::OptionMap &Opts) {
+  Options.store(Opts, "GslHeader", GslHeader);
+}
+
+void ProBoundsConstantArrayIndexCheck::registerPPCallbacks(
+CompilerInstance &Compiler) {
+  if (!getLangOpts().CPlusPlus)
+return;
+
+  Inserter.reset(new IncludeInserter(Compiler.getSourceManager(),
+ Compiler.getLangOpts(), IncludeStyle));
+  Compiler.getPreprocessor().addPPCallbacks(Inserter->CreatePPCallbacks());
+}
+
+void ProBoundsConstantArrayIndexCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+return;
+
+  Finder->addMatcher(arraySubscriptExpr(hasBase(ignoringImpCasts(hasType(
+ 

Re: [PATCH] D13746: [clang-tidy] add check cppcoreguidelines-pro-bounds-constant-array-index

2015-11-18 Thread Matthias Gehre via cfe-commits
mgehre added inline comments.


Comment at: 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp:2
@@ +1,3 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index 
%t -- -config='{CheckOptions: [{key: 
cppcoreguidelines-pro-bounds-constant-array-index.GslHeader, value: 
"dir1/gslheader.h"}]}' -- -std=c++11
+#include 
+// CHECK-FIXES: #include "dir1/gslheader.h"

chapuni wrote:
> Standard headers might be unavailable depending on a target, like host=linux 
> target=msvc.
> Could you improve it?
> 
> 
>   # Avoid 
>   # Introduce a new feature like "native"
> 
> 
Just to make sure that I understand this: The array header is unavailble 
because the target is a pre-C++11 msvc?

I can replace #include  by an stub definition of std::array. I'm not 
sure what you mean by 'Introduce a new feature like "native"'?


Repository:
  rL LLVM

http://reviews.llvm.org/D13746



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


[clang-tools-extra] r254182 - [clang-tidy] cppcoreguidelines-pro-bounds-pointer-arithmetic: ignore generated pointer arithmetic

2015-11-26 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Thu Nov 26 16:32:11 2015
New Revision: 254182

URL: http://llvm.org/viewvc/llvm-project?rev=254182&view=rev
Log:
[clang-tidy] cppcoreguidelines-pro-bounds-pointer-arithmetic: ignore generated 
pointer arithmetic

Summary:
Inside a range-based for-loop over an array, the compiler
generates pointer arithmetic (end = array + size). Don't flag this.

Reviewers: alexfh, sbenza, bkramer, aaron.ballman

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D14582

Modified:

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp

clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp?rev=254182&r1=254181&r2=254182&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
 Thu Nov 26 16:32:11 2015
@@ -22,9 +22,11 @@ void ProBoundsPointerArithmeticCheck::re
 
   // Flag all operators +, -, +=, -=, ++, -- that result in a pointer
   Finder->addMatcher(
-  binaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-"),
-   hasOperatorName("+="), hasOperatorName("-=")),
- hasType(pointerType()))
+  binaryOperator(
+  anyOf(hasOperatorName("+"), hasOperatorName("-"),
+hasOperatorName("+="), hasOperatorName("-=")),
+  hasType(pointerType()),
+  unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit()))
   .bind("expr"),
   this);
 
@@ -36,8 +38,10 @@ void ProBoundsPointerArithmeticCheck::re
 
   // Array subscript on a pointer (not an array) is also pointer arithmetic
   Finder->addMatcher(
-  arraySubscriptExpr(hasBase(ignoringImpCasts(anyOf(hasType(pointerType()),
-
hasType(decayedType(hasDecayedType(pointerType(
+  arraySubscriptExpr(
+  hasBase(ignoringImpCasts(
+  anyOf(hasType(pointerType()),
+hasType(decayedType(hasDecayedType(pointerType(
   .bind("expr"),
   this);
 }

Modified: 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp?rev=254182&r1=254181&r2=254182&view=diff
==
--- 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
 (original)
+++ 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
 Thu Nov 26 16:32:11 2015
@@ -84,4 +84,6 @@ void okay() {
   i = j - 1;
 
   auto diff = p - q; // OK, result is arithmetic
+
+  for(int ii : a) ; // OK, pointer arithmetic generated by compiler
 }


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


Re: [PATCH] D14582: [clang-tidy] cppcoreguidelines-pro-bounds-pointer-arithmetic: ignore generated pointer arithmetic

2015-11-26 Thread Matthias Gehre via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL254182: [clang-tidy] 
cppcoreguidelines-pro-bounds-pointer-arithmetic: ignore… (authored by mgehre).

Changed prior to commit:
  http://reviews.llvm.org/D14582?vs=40448&id=41272#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D14582

Files:
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
  
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp

Index: 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===
--- 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
+++ 
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -84,4 +84,6 @@
   i = j - 1;
 
   auto diff = p - q; // OK, result is arithmetic
+
+  for(int ii : a) ; // OK, pointer arithmetic generated by compiler
 }
Index: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
===
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -22,9 +22,11 @@
 
   // Flag all operators +, -, +=, -=, ++, -- that result in a pointer
   Finder->addMatcher(
-  binaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-"),
-   hasOperatorName("+="), hasOperatorName("-=")),
- hasType(pointerType()))
+  binaryOperator(
+  anyOf(hasOperatorName("+"), hasOperatorName("-"),
+hasOperatorName("+="), hasOperatorName("-=")),
+  hasType(pointerType()),
+  unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit()))
   .bind("expr"),
   this);
 
@@ -36,8 +38,10 @@
 
   // Array subscript on a pointer (not an array) is also pointer arithmetic
   Finder->addMatcher(
-  arraySubscriptExpr(hasBase(ignoringImpCasts(anyOf(hasType(pointerType()),
-
hasType(decayedType(hasDecayedType(pointerType(
+  arraySubscriptExpr(
+  hasBase(ignoringImpCasts(
+  anyOf(hasType(pointerType()),
+hasType(decayedType(hasDecayedType(pointerType(
   .bind("expr"),
   this);
 }


Index: clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -84,4 +84,6 @@
   i = j - 1;
 
   auto diff = p - q; // OK, result is arithmetic
+
+  for(int ii : a) ; // OK, pointer arithmetic generated by compiler
 }
Index: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
@@ -22,9 +22,11 @@
 
   // Flag all operators +, -, +=, -=, ++, -- that result in a pointer
   Finder->addMatcher(
-  binaryOperator(anyOf(hasOperatorName("+"), hasOperatorName("-"),
-   hasOperatorName("+="), hasOperatorName("-=")),
- hasType(pointerType()))
+  binaryOperator(
+  anyOf(hasOperatorName("+"), hasOperatorName("-"),
+hasOperatorName("+="), hasOperatorName("-=")),
+  hasType(pointerType()),
+  unless(hasLHS(ignoringImpCasts(declRefExpr(to(isImplicit()))
   .bind("expr"),
   this);
 
@@ -36,8 +38,10 @@
 
   // Array subscript on a pointer (not an array) is also pointer arithmetic
   Finder->addMatcher(
-  arraySubscriptExpr(hasBase(ignoringImpCasts(anyOf(hasType(pointerType()),
-hasType(decayedType(hasDecayedType(pointerType(
+  arraySubscriptExpr(
+  hasBase(ignoringImpCasts(
+  anyOf(hasType(pointerType()),
+hasType(decayedType(hasDecayedType(pointerType(
   .bind("expr"),
   this);
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D15030: [clang-tidy] add check cppcoreguidelines-pro-bounds-constant-array-index

2015-11-26 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added reviewers: alexfh, sbenza, bkramer, aaron.ballman.
mgehre added a subscriber: cfe-commits.

This is http://reviews.llvm.org/D13746 but instead of including ,
a stub is provided.
This check flags all array subscriptions on static arrays and
std::arrays that either have a non-compile-time-constant index or are
out of bounds.

Dynamic accesses into arrays are difficult for both tools and humans to
validate as safe. array_view is a bounds-checked, safe type for
accessing arrays of data. at() is another alternative that ensures
single accesses are bounds-checked. If iterators are needed to access an
array, use the iterators from an array_view constructed over the array.

This rule is part of the "Bounds safety" profile of the C++ Core
Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds2-only-index-into-arrays-using-constant-expressions

http://reviews.llvm.org/D15030

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
@@ -0,0 +1,79 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t -- -config='{CheckOptions: [{key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader, value: "dir1/gslheader.h"}]}' -- -std=c++11
+// CHECK-FIXES: #include "dir1/gslheader.h"
+
+typedef unsigned int size_t;
+
+namespace std {
+  template
+  struct array {
+T& operator[](size_t n);
+T& at(size_t n);
+  };
+}
+
+
+namespace gsl {
+  template
+  T& at( T(&a)[N], size_t index );
+
+  template
+  T& at( std::array &a, size_t index );
+}
+
+constexpr int const_index(int base) {
+  return base + 3;
+}
+
+void f(std::array a, int pos) {
+  a [ pos / 2 /*comment*/] = 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not a compile-time constant; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index]
+  // CHECK-FIXES: gsl::at(a,  pos / 2 /*comment*/) = 1;
+  int j = a[pos - 1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not a compile-time constant; use gsl::at() instead
+  // CHECK-FIXES: int j = gsl::at(a, pos - 1);
+
+  a.at(pos-1) = 2; // OK, at() instead of []
+  gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []
+
+  a[-1] = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is before the beginning of the array [cppcoreguidelines-pro-bounds-constant-array-index]
+  a[10] = 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index]
+
+  a[const_index(7)] = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)
+
+  a[0] = 3; // OK, constant index and inside bounds
+  a[1] = 3; // OK, constant index and inside bounds
+  a[9] = 3; // OK, constant index and inside bounds
+  a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+void g() {
+  int a[10];
+  for (int i = 0; i < 10; ++i) {
+a[i] = i;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not a compile-time constant; use gsl::at() instead
+// CHECK-FIXES: gsl::at(a, i) = i;
+gsl::at(a, i) = i; // OK, gsl::at() instead of []
+  }
+
+  a[-1] = 3; // flagged by clang-diagnostic-array-bounds
+  a[10] = 4; // flagged by clang-diagnostic-array-bounds
+  a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds
+
+  a[0] = 3; // OK, constant index and inside bounds
+  a[1] = 3; // OK, constant index and inside bounds
+  a[9] = 3; // OK, constant index and inside bounds
+  a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+struct S {
+  int& operator[](int i);
+};
+
+void customOperator() {
+  S s;
+  int i = 0;
+  s[i] = 3; // OK, custom operator
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -6,6 +6,7 @@
cert-thrown-exception-type
cert-variadic-function-def
cppcoreguidelines-pro-bounds-array-to-pointer-decay
+   cppcoreguidelines-pro-bounds-constant-array-index
cppcoreguidelines-pro-bounds-pointer-arithmetic
cppcoreguidelines-pro-type-const-cast
cppcoreguidelin

[PATCH] D15031: CFG: Add CFGElement for automatic variables that leave the scope

2015-11-26 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added reviewers: krememek, jordan_rose.
mgehre added a subscriber: cfe-commits.

This mimics the implementation for the implicit destructors. The
generation of this scope leaving elements is hidden behind
a flag to the CFGBuilder, thus it should not affect existing code.

Currently, I'm missing a test (it's implicitly tested by the clang-tidy
lifetime checker that I'm proposing).
I though about a test using debug.DumpCFG, but then I would
have to add an option to StaticAnalyzer/Core/AnalyzerOptions
to enable the scope leaving CFGElement,
which would only be useful to that particular test.

Any other ideas how I could make a test for this feature?

http://reviews.llvm.org/D15031

Files:
  include/clang/Analysis/CFG.h
  lib/Analysis/CFG.cpp

Index: lib/Analysis/CFG.cpp
===
--- lib/Analysis/CFG.cpp
+++ lib/Analysis/CFG.cpp
@@ -578,6 +578,10 @@
   CFGBlock *addInitializer(CXXCtorInitializer *I);
   void addAutomaticObjDtors(LocalScope::const_iterator B,
 LocalScope::const_iterator E, Stmt *S);
+  void addAutomaticObjLeavesScope(LocalScope::const_iterator B,
+  LocalScope::const_iterator E, Stmt *S);
+  void addAutomaticObjHandling(LocalScope::const_iterator B,
+   LocalScope::const_iterator E, Stmt *S);
   void addImplicitDtorsForDestructor(const CXXDestructorDecl *DD);
 
   // Local scopes creation.
@@ -618,13 +622,20 @@
 B->appendAutomaticObjDtor(VD, S, cfg->getBumpVectorContext());
   }
 
+  void appendAutomaticObjLeavesScope(CFGBlock *B, VarDecl *VD, Stmt *S) {
+B->appendAutomaticObjLeavesScope(VD, S, cfg->getBumpVectorContext());
+  }
+
   void appendDeleteDtor(CFGBlock *B, CXXRecordDecl *RD, CXXDeleteExpr *DE) {
 B->appendDeleteDtor(RD, DE, cfg->getBumpVectorContext());
   }
 
   void prependAutomaticObjDtorsWithTerminator(CFGBlock *Blk,
   LocalScope::const_iterator B, LocalScope::const_iterator E);
 
+  void prependAutomaticObjLeavesScopeWithTerminator(CFGBlock *Blk,
+  LocalScope::const_iterator B, LocalScope::const_iterator E);
+
   void addSuccessor(CFGBlock *B, CFGBlock *S, bool IsReachable = true) {
 B->addSuccessor(CFGBlock::AdjacentBlock(S, IsReachable),
 cfg->getBumpVectorContext());
@@ -1033,6 +1044,8 @@
   assert(Succ == &cfg->getExit());
   Block = nullptr;  // the EXIT block is empty.  Create all other blocks lazily.
 
+  assert(!(BuildOpts.AddImplicitDtors && BuildOpts.AddAutomaticObjLeavesScope) && "AddImplicitDtors and AddScopeLeavers cannot be used at the same time");
+
   if (BuildOpts.AddImplicitDtors)
 if (const CXXDestructorDecl *DD = dyn_cast_or_null(D))
   addImplicitDtorsForDestructor(DD);
@@ -1208,7 +1221,41 @@
 
   return Init->getType();
 }
-  
+
+void CFGBuilder::addAutomaticObjHandling(LocalScope::const_iterator B,
+ LocalScope::const_iterator E, Stmt *S) {
+  if (BuildOpts.AddImplicitDtors)
+addAutomaticObjDtors(B, E, S);
+  if (BuildOpts.AddAutomaticObjLeavesScope)
+addAutomaticObjLeavesScope(B, E, S);
+}
+
+/// addAutomaticObjLeavesScope - Add to current block automatic objects thats leave the scope.
+void CFGBuilder::addAutomaticObjLeavesScope(LocalScope::const_iterator B,
+LocalScope::const_iterator E, Stmt *S) {
+  if (!BuildOpts.AddAutomaticObjLeavesScope)
+return;
+
+  if (B == E)
+return;
+
+  int dist = B.distance(E);
+  if (dist <= 0)
+return;
+
+  // We need to perform the scope leaving in reverse order
+  SmallVector Decls;
+  Decls.reserve(dist);
+  for (LocalScope::const_iterator I = B; I != E; ++I)
+Decls.push_back(*I);
+
+  autoCreateBlock();
+  for (SmallVectorImpl::reverse_iterator I = Decls.rbegin(),
+   E = Decls.rend();
+   I != E; ++I)
+appendAutomaticObjLeavesScope(Block, *I, S);
+}
+
 /// addAutomaticObjDtors - Add to current block automatic objects destructors
 /// for objects in range of local scope positions. Use S as trigger statement
 /// for destructors.
@@ -1308,7 +1355,7 @@
 /// addLocalScopeForStmt - Add LocalScope to local scopes tree for statement
 /// that should create implicit scope (e.g. if/else substatements). 
 void CFGBuilder::addLocalScopeForStmt(Stmt *S) {
-  if (!BuildOpts.AddImplicitDtors)
+  if (!BuildOpts.AddImplicitDtors && !BuildOpts.AddAutomaticObjLeavesScope)
 return;
 
   LocalScope *Scope = nullptr;
@@ -1333,7 +1380,7 @@
 /// reuse Scope if not NULL.
 LocalScope* CFGBuilder::addLocalScopeForDeclStmt(DeclStmt *DS,
  LocalScope* Scope) {
-  if (!BuildOpts.AddImplicitDtors)
+  if (!BuildOpts.AddImplicitDtors && !BuildOpts.AddAutomaticObjLeavesScope)
 return Scope;
 
   for (auto *DI : DS->decls())
@@ -1347,7 +1394,7 @@
 /// const reference. Will reuse Scope if not NULL.
 

[PATCH] D15032: [clang-tidy] new checker cppcoreguidelines-pro-lifetime

2015-11-26 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added reviewers: alexfh, sbenza, bkramer, aaron.ballman.
mgehre added a subscriber: cfe-commits.
mgehre added a dependency: D15031: CFG: Add CFGElement for automatic variables 
that leave the scope.

This checker implements the lifetime rules presented in the paper
by Herb Sutter and Neil MacIntosh paper [1].
Basically, for each "Pointer" we track a set of possible "Owners" to which it
it directly or transitivly points, called its pset (points-to set).
If an Owner is invalidated, all Pointers that contain that Owner
in their pset get an "invalid" pset. For an in-depth explanation, please refer 
to the paper.

"Pointers" are not only variable with pointer type, but also references,
and objects that contain Pointers (e.g. iterators).

A pset can contain "null", "invalid", "static" (for static duration Owners that 
cannot
be invalidated), and tuples (Owner, order). Order 0 means that the
Pointer points to the object, e.g. int* p = &i => pset(p) = {(i,0)}.
Order 1 means that the Pointer points to something owned by the object,
e.g. int* p = o.getp() => pset(p) = {(o,1)}.

The paper, and thus the checker, are implemented in a path-independent
way. That leads to some false positives, but increases speed and
allows e.g. to reason about loops without unrolling.

Function bodies are analyzed separately. When calling a function,
the caller can assume how the psets of the Pointers change.
Those assumptions are checked for each analyzed function. (Just like for
const methods; callers assume that the object does not change; bodies of
const methods are not allowed to change the object).

The checker assumes that the code to be checked is valid
according to the C++ Core Guidelines type and bounds profile.
If "forbidden" expressions (such as pointer arithmetic) are used,
or if an unimplemented expression is encountered, the resulting pset
will be "unknown". Psets containing "unknown" will not cause any
warnings by the checker.

The checker will emit the pset of an variable if it finds a call to
"clang_analyzer_pset" in the C++ code. This is used by the tests to
display the pset of a Pointer.

For now, the checker is split into ProLifetimeCheck.cpp and
ProLifetimeVisitor.cpp. The only reason is that it speeds up the
compile time for me. ProLifetimeCheck.cpp is quite slow to compile
(I guess due to ASTMatchers.h). I can happily merge both cpp files before
the commiting, if required.

This checker is not complete. I would like to hear your comments
about high level stuff (e.g. architecture) and what is the best way
forward to get this upstream.

Currently state:
- Pointers are only variables of pointer type or reference type (no
objects containing Pointers, like iterators).
- Psets are computed through all expressions and conditionals.
- "(null)" will be removed from a pset in a branch
if the pointer appears in a conditional guarding that branch. It does
not handle all types of conditionals yet.
- Pointers are invalidated when the Owner they point to goes out of scope.
- Dereferencing invalid pointers is flagged.
- Pointers with static duration will be checked on assignment to only
have a pset of (null) and/or (static). Anything else is flagged.
- CFGs with loops are supported and lead to an iterative refinement
- I have run this on the llvm code base, and the diagnosed issues are mostly
  related to null pointer dereferencing. I would not call them
false-positives, because this checker assumes that pointer
arguments can be null, and otherwise gsl::not_null should be used.

If you like to see what it can diagnose, look at
  test/clang-tidy/cppcoreguidelines-pro-lifetime.cpp
For the internal pset propagation, look at
  test/clang-tidy/cppcoreguidelines-pro-lifetime-psets.cpp

(incomplete) TODO:
- track psets for objects containing Pointers
- compute pset of return values and out-parameters in function calls
- check correct pset in 'return' statments
- support annotations for non-standard lifetime behavior

[1] 
https://github.com/isocpp/CppCoreGuidelines/blob/master/docs/Lifetimes%20I%20and%20II%20-%20v0.9.1.pdf

Depends on D15031

http://reviews.llvm.org/D15032

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProLifetimeCheck.cpp
  clang-tidy/cppcoreguidelines/ProLifetimeCheck.h
  clang-tidy/cppcoreguidelines/ProLifetimeVisitor.cpp
  clang-tidy/cppcoreguidelines/ProLifetimeVisitor.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-lifetime.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-lifetime-psets.cpp
  test/clang-tidy/cppcoreguidelines-pro-lifetime.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-lifetime.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-lifetime.cpp
@@ -0,0 +1,87 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-lifetime %t -- -config="{CheckOptions: [{key: c

Re: [PATCH] D15031: CFG: Add CFGElement for automatic variables that leave the scope

2015-11-26 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

The lifetime checker that needs this is at http://reviews.llvm.org/D15032


http://reviews.llvm.org/D15031



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


Re: [PATCH] D15030: [clang-tidy] add check cppcoreguidelines-pro-bounds-constant-array-index

2015-12-09 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 42338.
mgehre added a comment.

Thanks for the comments!


http://reviews.llvm.org/D15030

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.rst
  docs/clang-tidy/checks/list.rst
  
test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp
  test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
@@ -0,0 +1,76 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t
+
+typedef unsigned int size_t;
+
+namespace std {
+  template
+  struct array {
+T& operator[](size_t n);
+T& at(size_t n);
+  };
+}
+
+
+namespace gsl {
+  template
+  T& at( T(&a)[N], size_t index );
+
+  template
+  T& at( std::array &a, size_t index );
+}
+
+constexpr int const_index(int base) {
+  return base + 3;
+}
+
+void f(std::array a, int pos) {
+  a [ pos / 2 /*comment*/] = 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index]
+  int j = a[pos - 1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+
+  a.at(pos-1) = 2; // OK, at() instead of []
+  gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []
+
+  a[-1] = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]
+  a[10] = 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index]
+
+  a[const_index(7)] = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)
+
+  a[0] = 3; // OK, constant index and inside bounds
+  a[1] = 3; // OK, constant index and inside bounds
+  a[9] = 3; // OK, constant index and inside bounds
+  a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+void g() {
+  int a[10];
+  for (int i = 0; i < 10; ++i) {
+a[i] = i;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+// CHECK-FIXES: gsl::at(a, i) = i;
+gsl::at(a, i) = i; // OK, gsl::at() instead of []
+  }
+
+  a[-1] = 3; // flagged by clang-diagnostic-array-bounds
+  a[10] = 4; // flagged by clang-diagnostic-array-bounds
+  a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds
+
+  a[0] = 3; // OK, constant index and inside bounds
+  a[1] = 3; // OK, constant index and inside bounds
+  a[9] = 3; // OK, constant index and inside bounds
+  a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+struct S {
+  int& operator[](int i);
+};
+
+void customOperator() {
+  S s;
+  int i = 0;
+  s[i] = 3; // OK, custom operator
+}
Index: test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp
@@ -0,0 +1,79 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t -- -config='{CheckOptions: [{key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader, value: "dir1/gslheader.h"}]}' -- -std=c++11
+// CHECK-FIXES: #include "dir1/gslheader.h"
+
+typedef unsigned int size_t;
+
+namespace std {
+  template
+  struct array {
+T& operator[](size_t n);
+T& at(size_t n);
+  };
+}
+
+
+namespace gsl {
+  template
+  T& at( T(&a)[N], size_t index );
+
+  template
+  T& at( std::array &a, size_t index );
+}
+
+constexpr int const_index(int base) {
+  return base + 3;
+}
+
+void f(std::array a, int pos) {
+  a [ pos / 2 /*comment*/] = 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index]
+  // CHECK-FIXES: gsl::at(a,  pos / 2 /*comment*/) = 1;
+  int j = a[pos - 1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+  // CHECK-FIXES: int j = gsl::at(a, pos - 1);
+
+  a.at(pos-1) = 2; // OK, at() instead of []
+  gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []
+
+  a

Re: [PATCH] D15030: [clang-tidy] add check cppcoreguidelines-pro-bounds-constant-array-index

2015-12-13 Thread Matthias Gehre via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL255470: [clang-tidy] add check 
cppcoreguidelines-pro-bounds-constant-array-index (authored by mgehre).

Changed prior to commit:
  http://reviews.llvm.org/D15030?vs=42338&id=42671#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D15030

Files:
  clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
  
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h
  
clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.rst
  clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
  
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp
  
clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp

Index: clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
@@ -0,0 +1,76 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t
+
+typedef unsigned int size_t;
+
+namespace std {
+  template
+  struct array {
+T& operator[](size_t n);
+T& at(size_t n);
+  };
+}
+
+
+namespace gsl {
+  template
+  T& at( T(&a)[N], size_t index );
+
+  template
+  T& at( std::array &a, size_t index );
+}
+
+constexpr int const_index(int base) {
+  return base + 3;
+}
+
+void f(std::array a, int pos) {
+  a [ pos / 2 /*comment*/] = 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index]
+  int j = a[pos - 1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+
+  a.at(pos-1) = 2; // OK, at() instead of []
+  gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []
+
+  a[-1] = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]
+  a[10] = 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index]
+
+  a[const_index(7)] = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)
+
+  a[0] = 3; // OK, constant index and inside bounds
+  a[1] = 3; // OK, constant index and inside bounds
+  a[9] = 3; // OK, constant index and inside bounds
+  a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+void g() {
+  int a[10];
+  for (int i = 0; i < 10; ++i) {
+a[i] = i;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+// CHECK-FIXES: gsl::at(a, i) = i;
+gsl::at(a, i) = i; // OK, gsl::at() instead of []
+  }
+
+  a[-1] = 3; // flagged by clang-diagnostic-array-bounds
+  a[10] = 4; // flagged by clang-diagnostic-array-bounds
+  a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds
+
+  a[0] = 3; // OK, constant index and inside bounds
+  a[1] = 3; // OK, constant index and inside bounds
+  a[9] = 3; // OK, constant index and inside bounds
+  a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+struct S {
+  int& operator[](int i);
+};
+
+void customOperator() {
+  S s;
+  int i = 0;
+  s[i] = 3; // OK, custom operator
+}
Index: clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp
@@ -0,0 +1,79 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t -- -config='{CheckOptions: [{key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader, value: "dir1/gslheader.h"}]}' -- -std=c++11
+// CHECK-FIXES: #include "dir1/gslheader.h"
+
+typedef unsigned int size_t;
+
+namespace std {
+  template
+  struct array {
+T& operator[](size_t n);
+T& at(size_t n);
+  };
+}
+
+
+namespace gsl {
+  template
+  T& at( T(&a)[N], size_t index );
+
+  template
+  T& at( std::array &a, size_t index );
+}
+
+constexpr int const_index(int base) {
+  ret

[clang-tools-extra] r255470 - [clang-tidy] add check cppcoreguidelines-pro-bounds-constant-array-index

2015-12-13 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Sun Dec 13 16:08:26 2015
New Revision: 255470

URL: http://llvm.org/viewvc/llvm-project?rev=255470&view=rev
Log:
[clang-tidy] add check cppcoreguidelines-pro-bounds-constant-array-index

Summary:
This is http://reviews.llvm.org/D13746 but instead of including ,
a stub is provided.
This check flags all array subscriptions on static arrays and
std::arrays that either have a non-compile-time-constant index or are
out of bounds.

Dynamic accesses into arrays are difficult for both tools and humans to
validate as safe. array_view is a bounds-checked, safe type for
accessing arrays of data. at() is another alternative that ensures
single accesses are bounds-checked. If iterators are needed to access an
array, use the iterators from an array_view constructed over the array.

This rule is part of the "Bounds safety" profile of the C++ Core
Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds2-only-index-into-arrays-using-constant-expressions

Reviewers: alexfh, sbenza, bkramer, aaron.ballman

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D15030

Added:

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h

clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-constant-array-index.rst

clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp

clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-bounds-constant-array-index.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt?rev=255470&r1=255469&r2=255470&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt 
(original)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt Sun Dec 
13 16:08:26 2015
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support)
 add_clang_library(clangTidyCppCoreGuidelinesModule
   CppCoreGuidelinesTidyModule.cpp
   ProBoundsArrayToPointerDecayCheck.cpp
+  ProBoundsConstantArrayIndexCheck.cpp
   ProBoundsPointerArithmeticCheck.cpp
   ProTypeConstCastCheck.cpp
   ProTypeCstyleCastCheck.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp?rev=255470&r1=255469&r2=255470&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
 Sun Dec 13 16:08:26 2015
@@ -12,6 +12,7 @@
 #include "../ClangTidyModuleRegistry.h"
 #include "../misc/AssignOperatorSignatureCheck.h"
 #include "ProBoundsArrayToPointerDecayCheck.h"
+#include "ProBoundsConstantArrayIndexCheck.h"
 #include "ProBoundsPointerArithmeticCheck.h"
 #include "ProTypeConstCastCheck.h"
 #include "ProTypeCstyleCastCheck.h"
@@ -30,6 +31,8 @@ public:
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {
 CheckFactories.registerCheck(
 "cppcoreguidelines-pro-bounds-array-to-pointer-decay");
+CheckFactories.registerCheck(
+"cppcoreguidelines-pro-bounds-constant-array-index");
 CheckFactories.registerCheck(
 "cppcoreguidelines-pro-bounds-pointer-arithmetic");
 CheckFactories.registerCheck(

Added: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp?rev=255470&view=auto
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
 (added)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp
 Sun Dec 13 16:08:26 2015
@@ -0,0 +1,132 @@
+//===--- ProBoundsConstantArrayIndexCheck.cpp - 
clang-tidy-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ProBoundsConstantArrayIndexCheck.h"
+#include

[PATCH] D13313: [clang-tidy] new check misc-no-reinterpret-cast

2015-09-30 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added a subscriber: cfe-commits.

This check flags all uses of reinterpret_cast in C++ code.

Use of these casts can violate type safety and cause the program to
access a variable that is actually of type X to be accessed as if it
were of an unrelated type Z.

This rule is part of the "Type safety" profile of the C++ Core
Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type1-dont-use-reinterpret_cast.

http://reviews.llvm.org/D13313

Files:
  clang-tidy/misc/CMakeLists.txt
  clang-tidy/misc/MiscTidyModule.cpp
  clang-tidy/misc/NoReinterpretCastCheck.cpp
  clang-tidy/misc/NoReinterpretCastCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/misc-no-reinterpret-cast.rst
  test/clang-tidy/misc-no-reinterpret-cast.cpp

Index: test/clang-tidy/misc-no-reinterpret-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/misc-no-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s misc-no-reinterpret-cast %t
+
+int i = 0;
+void* j;
+void f() { j = reinterpret_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast (C++ Core Guidelines, rule Type.1) [misc-no-reinterpret-cast]
\ No newline at end of file
Index: docs/clang-tidy/checks/misc-no-reinterpret-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/misc-no-reinterpret-cast.rst
@@ -0,0 +1,9 @@
+misc-no-reinterpret-cast
+
+
+This check flags all uses of reinterpret_cast in C++ code.
+
+Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type1-dont-use-reinterpret_cast.
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -31,6 +31,7 @@
misc-macro-repeated-side-effects
misc-move-constructor-init
misc-new-delete-overloads
+   misc-no-reinterpret-cast
misc-noexcept-move-constructor
misc-non-copyable-objects
misc-sizeof-container
Index: clang-tidy/misc/NoReinterpretCastCheck.h
===
--- /dev/null
+++ clang-tidy/misc/NoReinterpretCastCheck.h
@@ -0,0 +1,33 @@
+//===--- NoReinterpretCastCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NO_REINTERPRETCAST_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NO_REINTERPRETCAST_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// Flags all occurrences of reinterpret_cast 
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-no-reinterpret-cast.html
+class NoReinterpretCastCheck : public ClangTidyCheck {
+public:
+  NoReinterpretCastCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NO_REINTERPRETCAST_H
Index: clang-tidy/misc/NoReinterpretCastCheck.cpp
===
--- /dev/null
+++ clang-tidy/misc/NoReinterpretCastCheck.cpp
@@ -0,0 +1,34 @@
+//===--- NoReinterpretCastCheck.cpp - clang-tidy--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "NoReinterpretCastCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void NoReinterpretCastCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+return;
+  
+  Finder->addMatcher(cxxReinterpretCastExpr().bind("cast"), this);
+}
+
+void NoReinterpretCastCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedCast =
+  Result.Nodes.getNodeAs("cast");
+  diag(MatchedCast->getOperatorLoc(),
+   "do not use reinterpret_cast (C++ Core Guidelines, rule Type.1)");
+}

Re: [PATCH] D13313: [clang-tidy] new check misc-no-reinterpret-cast

2015-10-01 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36291.
mgehre added a comment.

Renamed the check to cppcoreguidelines-pro-type-reinterpret-cast


http://reviews.llvm.org/D13313

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/Makefile
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesModule.cpp
  clang-tidy/cppcoreguidelines/Makefile
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCast.cpp
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCast.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/Makefile
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void* j;
+void f() { j = reinterpret_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast (C++ Core Guidelines, rule Type.1) [cppcoreguidelines-pro-type-reinterpret-cast]
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-reinterpret-cast
+===
+
+This check flags all uses of reinterpret_cast in C++ code.
+
+Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type1-dont-use-reinterpret_cast.
Index: clang-tidy/tool/Makefile
===
--- clang-tidy/tool/Makefile
+++ clang-tidy/tool/Makefile
@@ -16,7 +16,9 @@
 
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
-USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
+USEDLIBS = clangTidy.a clangTidyLLVMModule.a \
+	   clangTidyCppCoreGuidelinesModule.a \
+	   clangTidyGoogleModule.a \
 	   clangTidyMiscModule.a clangTidyModernizeModule.a clangTidyReadability.a \
 	   clangTidyUtils.a clangStaticAnalyzerFrontend.a \
 	   clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -352,6 +352,11 @@
 static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =
 LLVMModuleAnchorSource;
 
+// This anchor is used to force the linker to link the CppCoreGuidelinesModule.
+extern volatile int CppCoreGuidelinesModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
+CppCoreGuidelinesModuleAnchorSource;
+
 // This anchor is used to force the linker to link the GoogleModule.
 extern volatile int GoogleModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -10,6 +10,7 @@
   clangASTMatchers
   clangBasic
   clangTidy
+  clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: clang-tidy/cppcoreguidelines/ProTypeReinterpretCast.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeReinterpretCast.h
@@ -0,0 +1,33 @@
+//===--- ProTypeReinterpretCast.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_H
+
+#include "../ClangTid

Re: [PATCH] D13313: [clang-tidy] new check misc-no-reinterpret-cast

2015-10-01 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36294.
mgehre added a comment.

Fix add_new_check.py for capitalization of CppCoreGuidelinesTidyModule.cpp


http://reviews.llvm.org/D13313

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/Makefile
  clang-tidy/add_new_check.py
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/Makefile
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCast.cpp
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCast.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/Makefile
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void* j;
+void f() { j = reinterpret_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast (C++ Core Guidelines, rule Type.1) [cppcoreguidelines-pro-type-reinterpret-cast]
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-reinterpret-cast
+===
+
+This check flags all uses of reinterpret_cast in C++ code.
+
+Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type1-dont-use-reinterpret_cast.
Index: clang-tidy/tool/Makefile
===
--- clang-tidy/tool/Makefile
+++ clang-tidy/tool/Makefile
@@ -16,7 +16,9 @@
 
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
-USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
+USEDLIBS = clangTidy.a clangTidyLLVMModule.a \
+	   clangTidyCppCoreGuidelinesModule.a \
+	   clangTidyGoogleModule.a \
 	   clangTidyMiscModule.a clangTidyModernizeModule.a clangTidyReadability.a \
 	   clangTidyUtils.a clangStaticAnalyzerFrontend.a \
 	   clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -352,6 +352,11 @@
 static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =
 LLVMModuleAnchorSource;
 
+// This anchor is used to force the linker to link the CppCoreGuidelinesModule.
+extern volatile int CppCoreGuidelinesModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
+CppCoreGuidelinesModuleAnchorSource;
+
 // This anchor is used to force the linker to link the GoogleModule.
 extern volatile int GoogleModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -10,6 +10,7 @@
   clangASTMatchers
   clangBasic
   clangTidy
+  clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: clang-tidy/cppcoreguidelines/ProTypeReinterpretCast.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeReinterpretCast.h
@@ -0,0 +1,33 @@
+//===--- ProTypeReinterpretCast.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYP

Re: [PATCH] D13313: [clang-tidy] new check misc-no-reinterpret-cast

2015-10-01 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36296.
mgehre added a comment.

Read 'Check' suffix on ProTypeReinterpretCastCheck


http://reviews.llvm.org/D13313

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/Makefile
  clang-tidy/add_new_check.py
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/Makefile
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/Makefile
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void* j;
+void f() { j = reinterpret_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast (C++ Core Guidelines, rule Type.1) [cppcoreguidelines-pro-type-reinterpret-cast]
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-reinterpret-cast
+===
+
+This check flags all uses of reinterpret_cast in C++ code.
+
+Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type1-dont-use-reinterpret_cast.
Index: clang-tidy/tool/Makefile
===
--- clang-tidy/tool/Makefile
+++ clang-tidy/tool/Makefile
@@ -16,7 +16,9 @@
 
 include $(CLANG_LEVEL)/../../Makefile.config
 LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
-USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
+USEDLIBS = clangTidy.a clangTidyLLVMModule.a \
+	   clangTidyCppCoreGuidelinesModule.a \
+	   clangTidyGoogleModule.a \
 	   clangTidyMiscModule.a clangTidyModernizeModule.a clangTidyReadability.a \
 	   clangTidyUtils.a clangStaticAnalyzerFrontend.a \
 	   clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -352,6 +352,11 @@
 static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =
 LLVMModuleAnchorSource;
 
+// This anchor is used to force the linker to link the CppCoreGuidelinesModule.
+extern volatile int CppCoreGuidelinesModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
+CppCoreGuidelinesModuleAnchorSource;
+
 // This anchor is used to force the linker to link the GoogleModule.
 extern volatile int GoogleModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -10,6 +10,7 @@
   clangASTMatchers
   clangBasic
   clangTidy
+  clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
@@ -0,0 +1,33 @@
+//===--- ProTypeReinterpretCast.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_CHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_T

Re: [PATCH] D13311: [clang-tidy] Add check misc-pointer-arithmetic

2015-10-01 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36300.
mgehre added a comment.

Port to cppcoreguidelines module.
Add checks for post/pre increment/decrement and array access.


http://reviews.llvm.org/D13311

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/Makefile
  clang-tidy/add_new_check.py
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/Makefile
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/Makefile
  docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
  test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void* j;
+void f() { j = reinterpret_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast (C++ Core Guidelines, rule Type.1) [cppcoreguidelines-pro-type-reinterpret-cast]
Index: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -0,0 +1,52 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+
+enum E {
+  ENUM_LITERAL = 1
+};
+
+int i = 4;
+int j = 1;
+int* p = 0;
+int* q = 0;
+
+void fail() {
+  q = p + 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  q = p - 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p += 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  q -= 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p = q - ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p = q + ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p++;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  ++p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p--;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  --p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  i = p[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+}
+
+void okey() {
+  int a[3];
+  i = a[2]; //OK, access to array
+
+  i++;
+  ++i;
+  i--;
+  --i;
+  i += 1;
+  i -= 1;
+  i = j + 1;
+  i = j - 1;
+
+  auto diff = p - q; //OK, result is arithmetic
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,8 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-bounds-pointer-arithmetic
+   cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-reinterpret-cast
+

Re: [PATCH] D13311: [clang-tidy] Add check misc-pointer-arithmetic

2015-10-01 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36305.
mgehre added a comment.

Remove inclusion of misc-no-reinterpret-cast in this patch set


http://reviews.llvm.org/D13311

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -0,0 +1,52 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+
+enum E {
+  ENUM_LITERAL = 1
+};
+
+int i = 4;
+int j = 1;
+int* p = 0;
+int* q = 0;
+
+void fail() {
+  q = p + 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  q = p - 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p += 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  q -= 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p = q - ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p = q + ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p++;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  ++p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p--;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  --p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  i = p[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic (C++ Core Guidelines, rule Bounds.1) [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+}
+
+void okey() {
+  int a[3];
+  i = a[2]; //OK, access to array
+
+  i++;
+  ++i;
+  i--;
+  --i;
+  i += 1;
+  i -= 1;
+  i = j + 1;
+  i = j - 1;
+
+  auto diff = p - q; //OK, result is arithmetic
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-bounds-pointer-arithmetic
cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
@@ -0,0 +1,10 @@
+cppcoreguidelines-pro-bounds-pointer-arithmetic
+===
+
+This check flags all usage of pointer arithmetic, because it could lead to an invalid pointer.
+Subtraction of two pointers is not flagged by this check.
+
+Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. array_view is a bounds-checked, safe type for accessing arrays of data.
+
+This rule is part of the "Bounds safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds1-dont-use-pointer-arithmetic-use-array_view-instead
Index: clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
@@ -0,0 +1,34 @@
+//===--- ProBoundsPointerArithmeticCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TX

[PATCH] D13368: [clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

2015-10-01 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added reviewers: alexfh, sbenza, bkramer, aaron.ballman.
mgehre added a subscriber: cfe-commits.
mgehre added a dependency: D13313: [clang-tidy] new check 
cppcoreguidelines-pro-type-reinterpret-cast.

This check flags all usages of static_cast, where a base class is casted
to a derived class.
In those cases, a fixit is provided to convert the cast to a
dynamic_cast.

Use of these casts can violate type safety and cause the program to
access a variable that is actually of type X to be accessed as if it
were of an unrelated type Z.

This rule is part of the "Type safety" profile of the C++ Core
Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type2-dont-use-static_cast-downcasts-use-dynamic_cast-instead

Depends on D13313

http://reviews.llvm.org/D13368

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
@@ -0,0 +1,60 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-static-cast-downcast %t
+
+class Base {
+};
+
+class Derived : public Base {
+};
+
+class Base2 {
+};
+
+class MultiDerived : public Base, public Base2 {
+};
+
+void pointers() {
+
+  auto B0 = static_cast(new Base());
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to cast from base to derived. Use dynamic_cast instead. (C++ Core Guidelines, rule Type.2) [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto B0 = dynamic_cast(new Base());
+
+  auto B1 = static_cast(new Derived()); // OK, upcast to a public base
+  auto B2 = static_cast(new MultiDerived()); // OK, upcast to a public base
+  auto B3 = static_cast(new MultiDerived()); // OK, upcast to a public base
+}
+
+void arrays() {
+  Base ArrayOfBase[10];
+  auto D0 = static_cast(ArrayOfBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to cast from base to derived. Use dynamic_cast instead. (C++ Core Guidelines, rule Type.2) [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto D0 = dynamic_cast(ArrayOfBase);
+}
+
+void references() {
+  Base B0;
+  Base& RefToBase = B0;
+  auto D0 = static_cast(RefToBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to cast from base to derived. Use dynamic_cast instead. (C++ Core Guidelines, rule Type.2) [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto D0 = dynamic_cast(RefToBase);
+
+  Derived d1;
+  auto b1 = static_cast(d1); // OK, upcast to a public base
+}
+
+template
+void templ_bad() {
+  auto B0 = static_cast(new D());
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to cast from base to derived. Use dynamic_cast instead. (C++ Core Guidelines, rule Type.2) [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto B0 = dynamic_cast(new D());
+}
+void templ_bad_call() {
+  templ_bad();
+}
+
+template
+void templ_good() {
+  auto B1 = static_cast(new D());
+}
+void templ_good_call() {
+templ_good(); // OK, upcast to a public base
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -3,6 +3,7 @@
 
 .. toctree::
cppcoreguidelines-pro-type-reinterpret-cast
+   cppcoreguidelines-pro-type-static-cast-downcast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst
@@ -0,0 +1,10 @@
+cppcoreguidelines-pro-type-static-cast-downcast
+===
+
+This check flags all usages of static_cast, where a base class is casted to a derived class.
+In those cases, a fixit is provided to convert the cast to a dynamic_cast.
+
+Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type2-dont-use-static_cast-downcasts-use-dynamic_cast-instead
Index: clang-tidy/cppcoreguidelines/

Re: [PATCH] D13313: [clang-tidy] new check cppcoreguidelines-pro-type-reinterpret-cast

2015-10-02 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36371.
mgehre added a comment.

Rebased
Removed "(C++ Core Guidelines, rule Type.1)" from diagnostic

Can someone please commit this?


http://reviews.llvm.org/D13313

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/Makefile
  clang-tidy/add_new_check.py
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/Makefile
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/Makefile
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void* j;
+void f() { j = reinterpret_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast (C++ Core Guidelines, rule Type.1) [cppcoreguidelines-pro-type-reinterpret-cast]
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-reinterpret-cast
+===
+
+This check flags all uses of reinterpret_cast in C++ code.
+
+Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type1-dont-use-reinterpret_cast.
Index: clang-tidy/tool/Makefile
===
--- clang-tidy/tool/Makefile
+++ clang-tidy/tool/Makefile
@@ -19,6 +19,7 @@
 USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
clangTidyMiscModule.a clangTidyModernizeModule.a clangTidyReadability.a \
 	   clangTidyUtils.a clangTidyCERTModule.a clangStaticAnalyzerFrontend.a \
+	   clangTidyCppCoreGuidelinesModule.a \
 	   clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
 	   clangFormat.a clangASTMatchers.a clangTooling.a clangToolingCore.a \
 	   clangFrontend.a clangSerialization.a clangDriver.a clangParse.a \
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -357,6 +357,11 @@
 static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =
 LLVMModuleAnchorSource;
 
+// This anchor is used to force the linker to link the CppCoreGuidelinesModule.
+extern volatile int CppCoreGuidelinesModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
+CppCoreGuidelinesModuleAnchorSource;
+
 // This anchor is used to force the linker to link the GoogleModule.
 extern volatile int GoogleModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -11,6 +11,7 @@
   clangBasic
   clangTidy
   clangTidyCERTModule
+  clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
@@ -0,0 +1,33 @@
+//===--- ProTypeReinterpretCast.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_CHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_

Re: [PATCH] D13313: [clang-tidy] new check cppcoreguidelines-pro-type-reinterpret-cast

2015-10-02 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36372.
mgehre added a comment.

Shot to fast, fixed test.

Now it's ready


http://reviews.llvm.org/D13313

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/Makefile
  clang-tidy/add_new_check.py
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/Makefile
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/Makefile
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void* j;
+void f() { j = reinterpret_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-reinterpret-cast
+===
+
+This check flags all uses of reinterpret_cast in C++ code.
+
+Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type1-dont-use-reinterpret_cast.
Index: clang-tidy/tool/Makefile
===
--- clang-tidy/tool/Makefile
+++ clang-tidy/tool/Makefile
@@ -19,6 +19,7 @@
 USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
clangTidyMiscModule.a clangTidyModernizeModule.a clangTidyReadability.a \
 	   clangTidyUtils.a clangTidyCERTModule.a clangStaticAnalyzerFrontend.a \
+	   clangTidyCppCoreGuidelinesModule.a \
 	   clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
 	   clangFormat.a clangASTMatchers.a clangTooling.a clangToolingCore.a \
 	   clangFrontend.a clangSerialization.a clangDriver.a clangParse.a \
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -357,6 +357,11 @@
 static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =
 LLVMModuleAnchorSource;
 
+// This anchor is used to force the linker to link the CppCoreGuidelinesModule.
+extern volatile int CppCoreGuidelinesModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
+CppCoreGuidelinesModuleAnchorSource;
+
 // This anchor is used to force the linker to link the GoogleModule.
 extern volatile int GoogleModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -11,6 +11,7 @@
   clangBasic
   clangTidy
   clangTidyCERTModule
+  clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
@@ -0,0 +1,33 @@
+//===--- ProTypeReinterpretCast.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_CHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_CHECK_H
+
+#include "../ClangTidy.h"
+
+namespace cl

Re: [PATCH] D13313: [clang-tidy] new check cppcoreguidelines-pro-type-reinterpret-cast

2015-10-02 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36399.
mgehre added a comment.

rebased


http://reviews.llvm.org/D13313

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/Makefile
  clang-tidy/add_new_check.py
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/Makefile
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/Makefile
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void* j;
+void f() { j = reinterpret_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-reinterpret-cast
+===
+
+This check flags all uses of reinterpret_cast in C++ code.
+
+Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type1-dont-use-reinterpret_cast.
Index: clang-tidy/tool/Makefile
===
--- clang-tidy/tool/Makefile
+++ clang-tidy/tool/Makefile
@@ -19,6 +19,7 @@
 USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
clangTidyMiscModule.a clangTidyModernizeModule.a clangTidyReadability.a \
 	   clangTidyUtils.a clangTidyCERTModule.a clangStaticAnalyzerFrontend.a \
+	   clangTidyCppCoreGuidelinesModule.a \
 	   clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
 	   clangFormat.a clangASTMatchers.a clangTooling.a clangToolingCore.a \
 	   clangFrontend.a clangSerialization.a clangDriver.a clangParse.a \
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -357,6 +357,11 @@
 static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =
 LLVMModuleAnchorSource;
 
+// This anchor is used to force the linker to link the CppCoreGuidelinesModule.
+extern volatile int CppCoreGuidelinesModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
+CppCoreGuidelinesModuleAnchorSource;
+
 // This anchor is used to force the linker to link the GoogleModule.
 extern volatile int GoogleModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -11,6 +11,7 @@
   clangBasic
   clangTidy
   clangTidyCERTModule
+  clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
@@ -0,0 +1,33 @@
+//===--- ProTypeReinterpretCast.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_CHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_CHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// Fla

Re: [PATCH] D13313: [clang-tidy] new check cppcoreguidelines-pro-type-reinterpret-cast

2015-10-02 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

I'm not sure what you mean by ToT. I rebased this against master @ 
http://llvm.org/git/clang-tools-extra.git


http://reviews.llvm.org/D13313



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


Re: [PATCH] D13311: [clang-tidy] Add check cppcoreguidelines-pro-bounds-pointer-arithmetic

2015-10-02 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36403.
mgehre marked 7 inline comments as done.
mgehre added a comment.

Incorporated comments
Simplied matcher: Instead of checking argument types, just check that the 
result of the arithmetic operation is a pointer


http://reviews.llvm.org/D13311

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -0,0 +1,83 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+
+enum E {
+  ENUM_LITERAL = 1
+};
+
+int i = 4;
+int j = 1;
+int* p = 0;
+int* q = 0;
+
+void fail() {
+  q = p + 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p = q + i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q + ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+  q = p - 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q - i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q - ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+  p += 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  p += i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  p += ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+  q -= 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  q -= i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  q -= ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+  p++;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+  ++p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+  p--;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+  --p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+  i = p[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
+}
+
+struct S {
+  operator int() const;
+};
+
+void f(S &s) {
+  int *i;
+  i = i + s;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+}
+
+void okay() {
+  int a[3];
+  i = a[2]; //OK, access to array
+
+  p = q;
+  p = &i;
+
+  i++;
+  ++i;
+  i--;
+  --i;
+  i += 1;
+  i -= 1;
+  i = j + 1;
+  i = j - 1;
+
+  auto diff = p - q; //OK, result is arithmetic
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-bounds-pointer-arithmetic
cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
@@ -0,0 +1,10 @@
+cppcoreguidelines-pro-bounds-pointer-arithmetic
+===
+
+This check flags all usage of pointer arithmetic, because it could lead to an invalid pointer.
+Subtraction of two pointers is not flagged by this check.
+
+Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. array_view is a bounds-checked, safe type for accessing arrays of data.
+
+This rule is part of the "Bounds safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds1-dont-use-pointer-arithmetic-use-array_view-instead
Index: clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
@@ -0,0 +1,35 @@
+//===--- ProBoundsPointerArithmeticCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--

Re: [PATCH] D13311: [clang-tidy] Add check cppcoreguidelines-pro-bounds-pointer-arithmetic

2015-10-02 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

Thank you for the review comments!



Comment at: clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp:38
@@ +37,3 @@
+  Finder->addMatcher(
+  arraySubscriptExpr(hasBase(implicitCastExpr(hasSourceExpression(
+ hasType(pointerType()).bind("expr"),

sbenza wrote:
> What is that implicitCastExpr() matching?
> Did you mean to use ignoringImpCasts() instead?
The AST for

```
int* p = 0;
int i;
i = p[1];

```
is

```
-BinaryOperator 0x22dd770  'int' lvalue '='
   |-DeclRefExpr 0x22dd6a8  'int' lvalue Var 0x227fca0 'i' 'int'
   `-ImplicitCastExpr 0x22dd758  'int' 
 `-ArraySubscriptExpr 0x22dd730  'int' lvalue
   |-ImplicitCastExpr 0x22dd718  'int *' 
   | `-DeclRefExpr 0x22dd6d0  'int *' lvalue Var 0x227fdf0 'p' 'int 
*'
   `-IntegerLiteral 0x22dd6f8  'int' 1

```
I guess you are right about ignoringImpCasts(), though.


http://reviews.llvm.org/D13311



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


Re: [PATCH] D13311: [clang-tidy] Add check cppcoreguidelines-pro-bounds-pointer-arithmetic

2015-10-02 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36404.
mgehre added a comment.

Fix typo


http://reviews.llvm.org/D13311

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -0,0 +1,83 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+
+enum E {
+  ENUM_LITERAL = 1
+};
+
+int i = 4;
+int j = 1;
+int* p = 0;
+int* q = 0;
+
+void fail() {
+  q = p + 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p = q + i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q + ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+  q = p - 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q - i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q - ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+  p += 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  p += i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  p += ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+  q -= 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  q -= i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  q -= ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+  p++;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+  ++p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+  p--;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+  --p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+  i = p[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
+}
+
+struct S {
+  operator int() const;
+};
+
+void f(S &s) {
+  int *i;
+  i = i + s;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+}
+
+void okay() {
+  int a[3];
+  i = a[2]; //OK, access to array
+
+  p = q;
+  p = &i;
+
+  i++;
+  ++i;
+  i--;
+  --i;
+  i += 1;
+  i -= 1;
+  i = j + 1;
+  i = j - 1;
+
+  auto diff = p - q; //OK, result is arithmetic
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-bounds-pointer-arithmetic
cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
@@ -0,0 +1,10 @@
+cppcoreguidelines-pro-bounds-pointer-arithmetic
+===
+
+This check flags all usage of pointer arithmetic, because it could lead to an invalid pointer.
+Subtraction of two pointers is not flagged by this check.
+
+Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. array_view is a bounds-checked, safe type for accessing arrays of data.
+
+This rule is part of the "Bounds safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds1-dont-use-pointer-arithmetic-use-array_view-instead
Index: clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
@@ -0,0 +1,35 @@
+//===--- ProBoundsPointerArithmeticCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_POINTER_ARITHMETIC_H
+#define

[PATCH] D13398: [clang-tidy] add check cppcoreguidelines-pro-type-const-cast

2015-10-02 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added reviewers: alexfh, sbenza, bkramer, aaron.ballman.
mgehre added a subscriber: cfe-commits.
mgehre added a dependency: D13313: [clang-tidy] new check 
cppcoreguidelines-pro-type-reinterpret-cast.

This check flags all uses of const_cast in C++ code.

Modifying a variable that was declared const is undefined behavior, even
with const_cast.

This rule is part of the "Type safety" profile of the C++ Core
Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type3-dont-use-const_cast-to-cast-away-const-ie-at-all.

Depends on D13313

http://reviews.llvm.org/D13398

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-const-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-const-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-const-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-const-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-const-cast %t
+
+const int* i;
+int* j;
+void f() { j = const_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-type-const-cast
cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-const-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-const-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-const-cast
+=
+
+This check flags all uses of const_cast in C++ code.
+
+Modifying a variable that was declared const is undefined behavior, even with const_cast.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type3-dont-use-const_cast-to-cast-away-const-ie-at-all.
Index: clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
@@ -0,0 +1,34 @@
+//===--- ProTypeConstCastCheck.h - clang-tidy*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_CONST_CAST_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_CONST_CAST_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// This check flags all instances of const_cast
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-type-const-cast.html
+class ProTypeConstCastCheck : public ClangTidyCheck {
+public:
+  ProTypeConstCastCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_CONST_CAST_H
+
Index: clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
@@ -0,0 +1,33 @@
+//===--- ProTypeConstCastCheck.cpp - clang-tidy===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ProTypeConstCastCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void ProTypeConstCastCheck::registerMatchers(MatchFinder *Finder) {
+  if(!getLangOpts().CPlusPlus)
+return;
+
+  Finder->addMatcher(cxxConstCastExpr().bind("cast"), this);
+}
+

Re: [PATCH] D13368: [clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

2015-10-04 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36465.
mgehre marked 3 inline comments as done.
mgehre added a comment.

Fixed comments. Only show fixit for polymorphic classes. Ignore template 
instantiations for now


http://reviews.llvm.org/D13368

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
@@ -0,0 +1,92 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-static-cast-downcast %t
+
+class Base {
+};
+
+class Derived : public Base {
+};
+
+class Base2 {
+};
+
+class MultiDerived : public Base, public Base2 {
+};
+
+class PolymorphicBase {
+public:
+  virtual ~PolymorphicBase();
+};
+
+class PolymorphicDerived : public PolymorphicBase {
+};
+
+class PolymorphicMultiDerived : public Base, public PolymorphicBase {
+};
+
+void pointers() {
+
+  auto P0 = static_cast(new Base());
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to cast from base class to derived class. [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  auto P1 = static_cast(new Derived()); // OK, upcast to a public base
+  auto P2 = static_cast(new MultiDerived()); // OK, upcast to a public base
+  auto P3 = static_cast(new MultiDerived()); // OK, upcast to a public base
+}
+
+void pointers_polymorphic() {
+
+  auto PP0 = static_cast(new PolymorphicBase());
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to cast from base class to derived class. Use dynamic_cast instead. [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto PP0 = dynamic_cast(new PolymorphicBase());
+
+  auto B1 = static_cast(new PolymorphicDerived()); // OK, upcast to a public base
+  auto B2 = static_cast(new PolymorphicMultiDerived()); // OK, upcast to a public base
+  auto B3 = static_cast(new PolymorphicMultiDerived()); // OK, upcast to a public base
+}
+
+void arrays() {
+  Base ArrayOfBase[10];
+  auto A0 = static_cast(ArrayOfBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to cast from base class to derived class. [cppcoreguidelines-pro-type-static-cast-downcast]
+}
+
+void arrays_polymorphic() {
+  PolymorphicBase ArrayOfPolymorphicBase[10];
+  auto AP0 = static_cast(ArrayOfPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to cast from base class to derived class. Use dynamic_cast instead. [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto AP0 = dynamic_cast(ArrayOfPolymorphicBase);
+}
+
+void references() {
+  Base B0;
+  Base& RefToBase = B0;
+  auto R0 = static_cast(RefToBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to cast from base class to derived class. [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  Derived RD1;
+  auto R1 = static_cast(RD1); // OK, upcast to a public base
+}
+
+void references_polymorphic() {
+  PolymorphicBase B0;
+  PolymorphicBase& RefToPolymorphicBase = B0;
+  auto RP0 = static_cast(RefToPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to cast from base class to derived class. Use dynamic_cast instead. [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto RP0 = dynamic_cast(RefToPolymorphicBase);
+
+  PolymorphicDerived d1;
+  auto RP1 = static_cast(d1); // OK, upcast to a public base
+}
+
+template
+void templ() {
+  auto B0 = static_cast(new D());
+}
+
+void templ_bad_call() {
+  templ(); //FIXME: this should trigger a warning
+}
+
+void templ_good_call() {
+  templ(); // OK, upcast to a public base
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -3,6 +3,7 @@
 
 .. toctree::
cppcoreguidelines-pro-type-reinterpret-cast
+   cppcoreguidelines-pro-type-static-cast-downcast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst
@@ -0,0 +1,10 @@
+cppcoreguidelines-pro-type-static-cast-downcast
+===
+
+This check flags all usages of static_cast, where a base class is casted to a derived class.
+In those cases, a fixi

Re: [PATCH] D13368: [clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

2015-10-04 Thread Matthias Gehre via cfe-commits
mgehre marked 2 inline comments as done.
mgehre added a comment.

Thank you for the detailed review.
I disabled checks in template instantiations for now.
Ideally, I would want to see something like:

  warning: do not use static_cast to cast from base class to derived class.
  note: in instantiation of function template specialization ... requested here 
...

This must be without fixit to no break other users of the template (e.g. where 
other users use non-polymorphic types).
How can I add that "note: in instantiation" line to the diagnostic of the check?


http://reviews.llvm.org/D13368



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


Re: [PATCH] D13313: [clang-tidy] new check cppcoreguidelines-pro-type-reinterpret-cast

2015-10-05 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36557.
mgehre added a comment.

Rebased


http://reviews.llvm.org/D13313

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/Makefile
  clang-tidy/add_new_check.py
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/Makefile
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/Makefile
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void* j;
+void f() { j = reinterpret_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -2,6 +2,7 @@
 =
 
 .. toctree::
+   cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-reinterpret-cast
+===
+
+This check flags all uses of reinterpret_cast in C++ code.
+
+Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type1-dont-use-reinterpret_cast.
Index: clang-tidy/tool/Makefile
===
--- clang-tidy/tool/Makefile
+++ clang-tidy/tool/Makefile
@@ -19,6 +19,7 @@
 USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
clangTidyMiscModule.a clangTidyModernizeModule.a clangTidyReadability.a \
 	   clangTidyUtils.a clangTidyCERTModule.a clangStaticAnalyzerFrontend.a \
+	   clangTidyCppCoreGuidelinesModule.a \
 	   clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
 	   clangFormat.a clangASTMatchers.a clangTooling.a clangToolingCore.a \
 	   clangFrontend.a clangSerialization.a clangDriver.a clangParse.a \
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -357,6 +357,11 @@
 static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =
 LLVMModuleAnchorSource;
 
+// This anchor is used to force the linker to link the CppCoreGuidelinesModule.
+extern volatile int CppCoreGuidelinesModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
+CppCoreGuidelinesModuleAnchorSource;
+
 // This anchor is used to force the linker to link the GoogleModule.
 extern volatile int GoogleModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -11,6 +11,7 @@
   clangBasic
   clangTidy
   clangTidyCERTModule
+  clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
@@ -0,0 +1,33 @@
+//===--- ProTypeReinterpretCast.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_CHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_CHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// Fla

Re: [PATCH] D13313: [clang-tidy] new check cppcoreguidelines-pro-type-reinterpret-cast

2015-10-05 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36561.
mgehre added a comment.

"arc diff" produced a invalid patch file (due to some file being "moved"?)
This patch is manually generated by git format-patch. I checked that it applies 
cleanly against svn trunk.


http://reviews.llvm.org/D13313

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/Makefile
  clang-tidy/add_new_check.py
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/Makefile
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  clang-tidy/tool/Makefile
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-reinterpret-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void* j;
+void f() { j = reinterpret_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -3,6 +3,7 @@
 
 .. toctree::
cert-variadic-function-def
+   cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-reinterpret-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-reinterpret-cast
+===
+
+This check flags all uses of reinterpret_cast in C++ code.
+
+Use of these casts can violate type safety and cause the program to access a variable that is actually of type X to be accessed as if it were of an unrelated type Z.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type1-dont-use-reinterpret_cast.
Index: clang-tidy/tool/Makefile
===
--- clang-tidy/tool/Makefile
+++ clang-tidy/tool/Makefile
@@ -19,6 +19,7 @@
 USEDLIBS = clangTidy.a clangTidyLLVMModule.a clangTidyGoogleModule.a \
clangTidyMiscModule.a clangTidyModernizeModule.a clangTidyReadability.a \
 	   clangTidyUtils.a clangTidyCERTModule.a clangStaticAnalyzerFrontend.a \
+	   clangTidyCppCoreGuidelinesModule.a \
 	   clangStaticAnalyzerCheckers.a clangStaticAnalyzerCore.a \
 	   clangFormat.a clangASTMatchers.a clangTooling.a clangToolingCore.a \
 	   clangFrontend.a clangSerialization.a clangDriver.a clangParse.a \
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -357,6 +357,11 @@
 static int LLVM_ATTRIBUTE_UNUSED LLVMModuleAnchorDestination =
 LLVMModuleAnchorSource;
 
+// This anchor is used to force the linker to link the CppCoreGuidelinesModule.
+extern volatile int CppCoreGuidelinesModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED CppCoreGuidelinesModuleAnchorDestination =
+CppCoreGuidelinesModuleAnchorSource;
+
 // This anchor is used to force the linker to link the GoogleModule.
 extern volatile int GoogleModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED GoogleModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt
===
--- clang-tidy/tool/CMakeLists.txt
+++ clang-tidy/tool/CMakeLists.txt
@@ -11,6 +11,7 @@
   clangBasic
   clangTidy
   clangTidyCERTModule
+  clangTidyCppCoreGuidelinesModule
   clangTidyGoogleModule
   clangTidyLLVMModule
   clangTidyMiscModule
Index: clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h
@@ -0,0 +1,33 @@
+//===--- ProTypeReinterpretCast.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_REINTERPRETCAST_C

Re: [PATCH] D13311: [clang-tidy] Add check cppcoreguidelines-pro-bounds-pointer-arithmetic

2015-10-05 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36564.
mgehre added a comment.

Fixed space after //


http://reviews.llvm.org/D13311

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
@@ -0,0 +1,82 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+enum E {
+  ENUM_LITERAL = 1
+};
+
+int i = 4;
+int j = 1;
+int *p = 0;
+int *q = 0;
+
+void fail() {
+  q = p + 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p = q + i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q + ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+  q = p - 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q - i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q - ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+  p += 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  p += i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  p += ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+  q -= 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  q -= i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  q -= ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+  p++;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+  ++p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+  p--;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+  --p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+  i = p[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
+}
+
+struct S {
+  operator int() const;
+};
+
+void f(S &s) {
+  int *i;
+  i = i + s;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+}
+
+void okay() {
+  int a[3];
+  i = a[2]; // OK, access to array
+
+  p = q;
+  p = &i;
+
+  i++;
+  ++i;
+  i--;
+  --i;
+  i += 1;
+  i -= 1;
+  i = j + 1;
+  i = j - 1;
+
+  auto diff = p - q; // OK, result is arithmetic
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -3,6 +3,7 @@
 
 .. toctree::
cert-variadic-function-def
+   cppcoreguidelines-pro-bounds-pointer-arithmetic
cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-pointer-arithmetic.rst
@@ -0,0 +1,10 @@
+cppcoreguidelines-pro-bounds-pointer-arithmetic
+===
+
+This check flags all usage of pointer arithmetic, because it could lead to an invalid pointer.
+Subtraction of two pointers is not flagged by this check.
+
+Pointers should only refer to single objects, and pointer arithmetic is fragile and easy to get wrong. array_view is a bounds-checked, safe type for accessing arrays of data.
+
+This rule is part of the "Bounds safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds1-dont-use-pointer-arithmetic-use-array_view-instead
Index: clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h
@@ -0,0 +1,34 @@
+//===--- ProBoundsPointerArithmeticCheck.h - clang-tidy--*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_POINTER_ARITH

Re: [PATCH] D13368: [clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

2015-10-05 Thread Matthias Gehre via cfe-commits
mgehre marked an inline comment as done.


Comment at: clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp:53
@@ +52,3 @@
+  } else {
+diag(MatchedCast->getOperatorLoc(), "do not use static_cast to cast from 
base class to derived class.");
+  }

aaron.ballman wrote:
> What is the alternative the user should use in this instance?
The alternative is to either
1) change the program logic to not require and downcast of a non-polymorphic 
type
or
2) add NOLINT to notify your coworkers that this may be the spot where 
something goes wrong

In the end, these rules together should eliminate some classes of undefined 
behavior and crashes. If the application still crashes,
you should just need to look at the (hopefully few) places of NOLINT.

Anyway, I didn't make the rules. See Herb Sutters answer here: 
https://github.com/isocpp/CppCoreGuidelines/issues/270


http://reviews.llvm.org/D13368



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


Re: [PATCH] D13368: [clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

2015-10-05 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36567.
mgehre marked 2 inline comments as done.
mgehre added a comment.

Simplify logic to check for BaseToDerived cast. Add test for object to 
reference cast. Fixed comments


http://reviews.llvm.org/D13368

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
@@ -0,0 +1,99 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-static-cast-downcast %t
+
+class Base {
+};
+
+class Derived : public Base {
+};
+
+class Base2 {
+};
+
+class MultiDerived : public Base, public Base2 {
+};
+
+class PolymorphicBase {
+public:
+  virtual ~PolymorphicBase();
+};
+
+class PolymorphicDerived : public PolymorphicBase {
+};
+
+class PolymorphicMultiDerived : public Base, public PolymorphicBase {
+};
+
+void pointers() {
+
+  auto P0 = static_cast(new Base());
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  auto P1 = static_cast(new Derived()); // OK, upcast to a public base
+  auto P2 = static_cast(new MultiDerived()); // OK, upcast to a public base
+  auto P3 = static_cast(new MultiDerived()); // OK, upcast to a public base
+}
+
+void pointers_polymorphic() {
+
+  auto PP0 = static_cast(new PolymorphicBase());
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto PP0 = dynamic_cast(new PolymorphicBase());
+
+  auto B1 = static_cast(new PolymorphicDerived()); // OK, upcast to a public base
+  auto B2 = static_cast(new PolymorphicMultiDerived()); // OK, upcast to a public base
+  auto B3 = static_cast(new PolymorphicMultiDerived()); // OK, upcast to a public base
+}
+
+void arrays() {
+  Base ArrayOfBase[10];
+  auto A0 = static_cast(ArrayOfBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+}
+
+void arrays_polymorphic() {
+  PolymorphicBase ArrayOfPolymorphicBase[10];
+  auto AP0 = static_cast(ArrayOfPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto AP0 = dynamic_cast(ArrayOfPolymorphicBase);
+}
+
+void references() {
+  Base B0;
+  auto R0 = static_cast(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+  Base& RefToBase = B0;
+  auto R1 = static_cast(RefToBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  Derived RD1;
+  auto R2 = static_cast(RD1); // OK, upcast to a public base
+}
+
+void references_polymorphic() {
+  PolymorphicBase B0;
+  auto RP0 = static_cast(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto RP0 = dynamic_cast(B0);
+
+
+  PolymorphicBase& RefToPolymorphicBase = B0;
+  auto RP1 = static_cast(RefToPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto RP1 = dynamic_cast(RefToPolymorphicBase);
+
+  PolymorphicDerived d1;
+  auto RP2 = static_cast(d1); // OK, upcast to a public base
+}
+
+template
+void templ() {
+  auto B0 = static_cast(new D());
+}
+
+void templ_bad_call() {
+  templ(); //FIXME: this should trigger a warning
+}
+
+void templ_good_call() {
+  templ(); // OK, upcast to a public base
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -4,6 +4,7 @@
 .. toctree::
cert-variadic-function-def
cppcoreguidelines-pro-type-reinterpret-cast
+   cppcoreguidelines-pro-type-static-cast-downcast
google-build-explicit-make-pair
google-build-namespaces
  

Re: [PATCH] D13368: [clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

2015-10-05 Thread Matthias Gehre via cfe-commits
mgehre added inline comments.


Comment at: clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp:33
@@ +32,3 @@
+  const auto *SourceDecl = SourceType->getPointeeCXXRecordDecl();
+  if(!SourceDecl)
+SourceDecl = SourceType->getAsCXXRecordDecl();

aaron.ballman wrote:
> In the event it's not a pointer or a reference, why are you getting the 
> source as a value type?
Source type could be no pointer nor ref like in:
   Base B0;
   auto R0 = static_cast(B0);
 


http://reviews.llvm.org/D13368



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


Re: [PATCH] D13311: [clang-tidy] Add check cppcoreguidelines-pro-bounds-pointer-arithmetic

2015-10-06 Thread Matthias Gehre via cfe-commits
mgehre marked 2 inline comments as done.


Comment at: 
test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp:37
@@ +36,3 @@
+  q -= i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  q -= ENUM_LITERAL;

aaron.ballman wrote:
> I don't think this comment is "done" yet. I still don't know how this check 
> is intended to handle code like that. Does it currently diagnose? Does it not 
> diagnose? Should it diagnose?
I had added your code, see line 55 of this file.
It should diagnose, because an arithmetic operation (+) is used, which results 
in a (possibly) changed pointer.
It does diagnose, as the CHECK-MESSAGE shows.


Comment at: 
test/clang-tidy/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp:51
@@ +50,3 @@
+
+  i = p[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic

aaron.ballman wrote:
> How well does this handle code like:
> ```
> void f(int i[], size_t s) {
>   i[s - 1] = 0;
> }
> ```
> Does it diagnose, and should it?
Good point, I'll ask at https://github.com/isocpp/CppCoreGuidelines/issues/299


http://reviews.llvm.org/D13311



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


Re: [PATCH] D13368: [clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

2015-10-06 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36664.
mgehre added a comment.

Remove trailing [cppcoreguidelines-pro-type-static-cast-downcast] on tests


http://reviews.llvm.org/D13368

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
@@ -0,0 +1,99 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-static-cast-downcast %t
+
+class Base {
+};
+
+class Derived : public Base {
+};
+
+class Base2 {
+};
+
+class MultiDerived : public Base, public Base2 {
+};
+
+class PolymorphicBase {
+public:
+  virtual ~PolymorphicBase();
+};
+
+class PolymorphicDerived : public PolymorphicBase {
+};
+
+class PolymorphicMultiDerived : public Base, public PolymorphicBase {
+};
+
+void pointers() {
+
+  auto P0 = static_cast(new Base());
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  auto P1 = static_cast(new Derived()); // OK, upcast to a public base
+  auto P2 = static_cast(new MultiDerived()); // OK, upcast to a public base
+  auto P3 = static_cast(new MultiDerived()); // OK, upcast to a public base
+}
+
+void pointers_polymorphic() {
+
+  auto PP0 = static_cast(new PolymorphicBase());
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto PP0 = dynamic_cast(new PolymorphicBase());
+
+  auto B1 = static_cast(new PolymorphicDerived()); // OK, upcast to a public base
+  auto B2 = static_cast(new PolymorphicMultiDerived()); // OK, upcast to a public base
+  auto B3 = static_cast(new PolymorphicMultiDerived()); // OK, upcast to a public base
+}
+
+void arrays() {
+  Base ArrayOfBase[10];
+  auto A0 = static_cast(ArrayOfBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+}
+
+void arrays_polymorphic() {
+  PolymorphicBase ArrayOfPolymorphicBase[10];
+  auto AP0 = static_cast(ArrayOfPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto AP0 = dynamic_cast(ArrayOfPolymorphicBase);
+}
+
+void references() {
+  Base B0;
+  auto R0 = static_cast(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+  Base& RefToBase = B0;
+  auto R1 = static_cast(RefToBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  Derived RD1;
+  auto R2 = static_cast(RD1); // OK, upcast to a public base
+}
+
+void references_polymorphic() {
+  PolymorphicBase B0;
+  auto RP0 = static_cast(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto RP0 = dynamic_cast(B0);
+
+
+  PolymorphicBase& RefToPolymorphicBase = B0;
+  auto RP1 = static_cast(RefToPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto RP1 = dynamic_cast(RefToPolymorphicBase);
+
+  PolymorphicDerived d1;
+  auto RP2 = static_cast(d1); // OK, upcast to a public base
+}
+
+template
+void templ() {
+  auto B0 = static_cast(new D());
+}
+
+void templ_bad_call() {
+  templ(); //FIXME: this should trigger a warning
+}
+
+void templ_good_call() {
+  templ(); // OK, upcast to a public base
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -4,6 +4,7 @@
 .. toctree::
cert-variadic-function-def
cppcoreguidelines-pro-type-reinterpret-cast
+   cppcoreguidelines-pro-type-static-cast-downcast
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst

Re: [PATCH] D13368: [clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

2015-10-06 Thread Matthias Gehre via cfe-commits
mgehre marked an inline comment as done.
mgehre added a comment.

I cannot think of any way to improve the usefulness of the diagnostic in the 
non-polymorphic case.
For now, this patch has a link to the CppCoreGuidelines document in the 
docs/**/*.rst file.

Also, this check is not enabled by default. One has to explicitly enable it, 
and may at that
point reason about the usefulness of the CppCoreGuidelines and this check.



Comment at: 
test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp:39
@@ +38,3 @@
+  auto PP0 = static_cast(new PolymorphicBase());
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to 
downcast from a base to a derived class; use dynamic_cast instead 
[cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto PP0 = dynamic_cast(new 
PolymorphicBase());

aaron.ballman wrote:
> No need to have the [cppcoreguidelines-pro-type-static-cast-downcast] part of 
> the message on anything but the first diagnostic in the file. (This reduces 
> clutter, but we test it one time just to make sure it's there).
I can remove it on the remaining messages that end in "use dynamic_cast 
instead". I need to keep it in the non-polymorphic case
to make sure that they are not followed by "use dynamic_cast instead".


http://reviews.llvm.org/D13368



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


Re: [PATCH] D13398: [clang-tidy] add check cppcoreguidelines-pro-type-const-cast

2015-10-06 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 36668.
mgehre added a comment.

Rebased


http://reviews.llvm.org/D13398

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-const-cast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-const-cast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-const-cast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-const-cast.cpp
@@ -0,0 +1,6 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-const-cast %t
+
+const int* i;
+int* j;
+void f() { j = const_cast(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -3,6 +3,7 @@
 
 .. toctree::
cert-variadic-function-def
+   cppcoreguidelines-pro-type-const-cast
cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
google-build-namespaces
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-type-const-cast.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-type-const-cast.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-type-const-cast
+=
+
+This check flags all uses of const_cast in C++ code.
+
+Modifying a variable that was declared const is undefined behavior, even with const_cast.
+
+This rule is part of the "Type safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type3-dont-use-const_cast-to-cast-away-const-ie-at-all.
Index: clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h
@@ -0,0 +1,34 @@
+//===--- ProTypeConstCastCheck.h - clang-tidy*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_CONST_CAST_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_CONST_CAST_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// This check flags all instances of const_cast
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-type-const-cast.html
+class ProTypeConstCastCheck : public ClangTidyCheck {
+public:
+  ProTypeConstCastCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_TYPE_CONST_CAST_H
+
Index: clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp
@@ -0,0 +1,33 @@
+//===--- ProTypeConstCastCheck.cpp - clang-tidy===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ProTypeConstCastCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void ProTypeConstCastCheck::registerMatchers(MatchFinder *Finder) {
+  if(!getLangOpts().CPlusPlus)
+return;
+
+  Finder->addMatcher(cxxConstCastExpr().bind("cast"), this);
+}
+
+void ProTypeConstCastCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *MatchedCast = Result.Nodes.getNodeAs("cast");
+  diag(MatchedCast->getOperatorLoc(), "do not use const_cast");
+}
+
+} // namespace tidy
+} // namespace clang
+
Index: clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
===
--- clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
+++ clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
@@ -10,6 +10,7 

Re: [PATCH] D13440: [clang-tidy] Python script for easy check rename

2015-10-07 Thread Matthias Gehre via cfe-commits
mgehre added a subscriber: mgehre.


Comment at: clang-tidy/rename_check.py:39
@@ +38,3 @@
+  if len(sys.argv) != 4:
+print('Usage: rename_check.py  , e.g.\n')
+print('rename_check.py misc awesome-functions new-awesome-function\n')

Should be
```
Usage: rename_check.py   
```
?


Repository:
  rL LLVM

http://reviews.llvm.org/D13440



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


Re: [PATCH] D13510: [PATCH] Support C++ Core Guidelines copy assignment restrictions

2015-10-07 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

The user will see [cppcoreguidelines-c-copy-assignment-signature] in warnings, 
but there is no
docs/clang-tidy/checks/cppcoreguidelines-c-copy-assignment-signature.rst.

The user won't know that he needs to look for misc-assign-operator-signature.

Maybe create a link to 
docs/clang-tidy/checks/misc-assign-operator-signature.rst?
(and also add it to docs/clang-tidy/checks/list.rst)

Also, users reading the documentation will not see that 
cppcoreguidelines-c-copy-assignment-signature is available.


http://reviews.llvm.org/D13510



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


r307759 - CFG: Add CFGElement for automatic variables that leave the scope

2017-07-12 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Wed Jul 12 00:04:19 2017
New Revision: 307759

URL: http://llvm.org/viewvc/llvm-project?rev=307759&view=rev
Log:
CFG: Add CFGElement for automatic variables that leave the scope

Summary:
This mimics the implementation for the implicit destructors. The
generation of this scope leaving elements is hidden behind
a flag to the CFGBuilder, thus it should not affect existing code.

Currently, I'm missing a test (it's implicitly tested by the clang-tidy
lifetime checker that I'm proposing).
I though about a test using debug.DumpCFG, but then I would
have to add an option to StaticAnalyzer/Core/AnalyzerOptions
to enable the scope leaving CFGElement,
which would only be useful to that particular test.

Any other ideas how I could make a test for this feature?

Reviewers: krememek, jordan_rose

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D15031

Added:
cfe/trunk/test/Analysis/lifetime-cfg-output.cpp
Modified:
cfe/trunk/include/clang/Analysis/AnalysisContext.h
cfe/trunk/include/clang/Analysis/CFG.h
cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
cfe/trunk/test/Analysis/analyzer-config.c
cfe/trunk/test/Analysis/analyzer-config.cpp

Modified: cfe/trunk/include/clang/Analysis/AnalysisContext.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/AnalysisContext.h?rev=307759&r1=307758&r2=307759&view=diff
==
--- cfe/trunk/include/clang/Analysis/AnalysisContext.h (original)
+++ cfe/trunk/include/clang/Analysis/AnalysisContext.h Wed Jul 12 00:04:19 2017
@@ -426,6 +426,7 @@ public:
  bool addImplicitDtors = false,
  bool addInitializers = false,
  bool addTemporaryDtors = false,
+ bool addLifetime = false,
  bool synthesizeBodies = false,
  bool addStaticInitBranches = false,
  bool addCXXNewAllocator = true,

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=307759&r1=307758&r2=307759&view=diff
==
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Wed Jul 12 00:04:19 2017
@@ -58,6 +58,7 @@ public:
 Statement,
 Initializer,
 NewAllocator,
+LifetimeEnds,
 // dtor kind
 AutomaticObjectDtor,
 DeleteDtor,
@@ -167,6 +168,28 @@ private:
   }
 };
 
+/// Represents the point where the lifetime of an automatic object ends
+class CFGLifetimeEnds : public CFGElement {
+public:
+  explicit CFGLifetimeEnds(const VarDecl *var, const Stmt *stmt)
+  : CFGElement(LifetimeEnds, var, stmt) {}
+
+  const VarDecl *getVarDecl() const {
+return static_cast(Data1.getPointer());
+  }
+
+  const Stmt *getTriggerStmt() const {
+return static_cast(Data2.getPointer());
+  }
+
+private:
+  friend class CFGElement;
+  CFGLifetimeEnds() {}
+  static bool isKind(const CFGElement &elem) {
+return elem.getKind() == LifetimeEnds;
+  }
+};
+
 /// CFGImplicitDtor - Represents C++ object destructor implicitly generated
 /// by compiler on various occasions.
 class CFGImplicitDtor : public CFGElement {
@@ -701,6 +724,10 @@ public:
 Elements.push_back(CFGAutomaticObjDtor(VD, S), C);
   }
 
+  void appendLifetimeEnds(VarDecl *VD, Stmt *S, BumpVectorContext &C) {
+Elements.push_back(CFGLifetimeEnds(VD, S), C);
+  }
+
   void appendDeleteDtor(CXXRecordDecl *RD, CXXDeleteExpr *DE, 
BumpVectorContext &C) {
 Elements.push_back(CFGDeleteDtor(RD, DE), C);
   }
@@ -717,6 +744,19 @@ public:
 *I = CFGAutomaticObjDtor(VD, S);
 return ++I;
   }
+
+  // Scope leaving must be performed in reversed order. So insertion is in two
+  // steps. First we prepare space for some number of elements, then we insert
+  // the elements beginning at the last position in prepared space.
+  iterator beginLifetimeEndsInsert(iterator I, size_t Cnt,
+   BumpVectorContext &C) {
+return iterator(
+Elements.insert(I.base(), Cnt, CFGLifetimeEnds(nullptr, nullptr), C));
+  }
+  iterator insertLifetimeEnds(iterator I, VarDecl *VD, Stmt *S) {
+*I = CFGLifetimeEnds(VD, S);
+return ++I;
+  }
 };
 
 /// \brief CFGCallback defines methods that should be called when a logical
@@ -753,6 +793,7 @@ public:
 bool AddEHEdges;
 bool AddInitializers;
 bool AddImplicitDtors;
+bool AddLifetime;
 bool 

r299465 - [clang-format] fix crash in NamespaceEndCommentsFixer (PR32438)

2017-04-04 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Tue Apr  4 15:11:13 2017
New Revision: 299465

URL: http://llvm.org/viewvc/llvm-project?rev=299465&view=rev
Log:
[clang-format] fix crash in NamespaceEndCommentsFixer (PR32438)

Summary:
The new test case was crashing before. Now it passes
as expected.

Reviewers: djasper

Subscribers: klimek, cfe-commits

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

Modified:
cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp
cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp

Modified: cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp?rev=299465&r1=299464&r2=299465&view=diff
==
--- cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp (original)
+++ cfe/trunk/lib/Format/NamespaceEndCommentsFixer.cpp Tue Apr  4 15:11:13 2017
@@ -133,7 +133,7 @@ tooling::Replacements NamespaceEndCommen
 // Detect "(inline)? namespace" in the beginning of a line.
 if (NamespaceTok->is(tok::kw_inline))
   NamespaceTok = NamespaceTok->getNextNonComment();
-if (NamespaceTok->isNot(tok::kw_namespace))
+if (!NamespaceTok || NamespaceTok->isNot(tok::kw_namespace))
   continue;
 FormatToken *RBraceTok = EndLine->First;
 if (RBraceTok->Finalized)

Modified: cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp?rev=299465&r1=299464&r2=299465&view=diff
==
--- cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp (original)
+++ cfe/trunk/unittests/Format/NamespaceEndCommentsFixerTest.cpp Tue Apr  4 
15:11:13 2017
@@ -582,6 +582,21 @@ TEST_F(NamespaceEndCommentsFixerTest,
 "} // namespace\n"
 "}"));
 }
+
+TEST_F(NamespaceEndCommentsFixerTest, HandlesInlineAtEndOfLine_PR32438) {
+  EXPECT_EQ("template  struct a {};\n"
+"struct a b() {\n"
+"}\n"
+"#define c inline\n"
+"void d() {\n"
+"}\n",
+fixNamespaceEndComments("template  struct a {};\n"
+"struct a b() {\n"
+"}\n"
+"#define c inline\n"
+"void d() {\n"
+"}\n"));
+}
 } // end namespace
 } // end namespace format
 } // end namespace clang


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


[PATCH] D22069: clang-tidy modernize-loop-convert: preserve type of alias declaration (bug 28341)

2016-07-06 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added reviewers: alexfh, klimek.
mgehre added a subscriber: cfe-commits.

Previoly, the added test failed with the fillowing fixit:

 char v[5];

-for(size_t i = 0; i < 5; ++i)
+for(char value : v)
 {
-unsigned char value = v[i];
 if (value > 127)

i.e. the variable 'value' changes from unsigned char to signed char. And
thus the following 'if' does not work anymore.

With this commit, the fixit is changed to:
 char v[5];

-for(size_t i = 0; i < 5; ++i)
+for(unsigned char value : v)
 {
-unsigned char value = v[i];
 if (value > 127)

http://reviews.llvm.org/D22069

Files:
  clang-tidy/modernize/LoopConvertCheck.cpp
  test/clang-tidy/modernize-loop-convert-extra.cpp

Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -1060,3 +1060,15 @@
 }
 
 } // namespace InitLists
+
+void bug28341() {
+  char v[5];
+  for(int i = 0; i < 5; ++i) {
+  unsigned char value = v[i];
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for(unsigned char value : v)
+  // CHECK-FIXES-NOT: unsigned char value = v[i];
+  if (value > 127)
+;
+  }
+}
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -517,6 +517,15 @@
   if (VarNameFromAlias) {
 const auto *AliasVar = cast(AliasDecl->getSingleDecl());
 VarName = AliasVar->getName().str();
+
+// Use the type of the alias if it's not the same
+QualType DeclarationType = AliasVar->getType();
+if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
+  DeclarationType = DeclarationType.getNonReferenceType();
+if (Descriptor.ElemType.isNull() || DeclarationType.isNull() ||
+!Context->hasSameUnqualifiedType(DeclarationType, Descriptor.ElemType))
+  Descriptor.ElemType = AliasVar->getType();
+
 AliasVarIsRef = AliasVar->getType()->isReferenceType();
 
 // We keep along the entire DeclStmt to keep the correct range here.


Index: test/clang-tidy/modernize-loop-convert-extra.cpp
===
--- test/clang-tidy/modernize-loop-convert-extra.cpp
+++ test/clang-tidy/modernize-loop-convert-extra.cpp
@@ -1060,3 +1060,15 @@
 }
 
 } // namespace InitLists
+
+void bug28341() {
+  char v[5];
+  for(int i = 0; i < 5; ++i) {
+  unsigned char value = v[i];
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for(unsigned char value : v)
+  // CHECK-FIXES-NOT: unsigned char value = v[i];
+  if (value > 127)
+;
+  }
+}
Index: clang-tidy/modernize/LoopConvertCheck.cpp
===
--- clang-tidy/modernize/LoopConvertCheck.cpp
+++ clang-tidy/modernize/LoopConvertCheck.cpp
@@ -517,6 +517,15 @@
   if (VarNameFromAlias) {
 const auto *AliasVar = cast(AliasDecl->getSingleDecl());
 VarName = AliasVar->getName().str();
+
+// Use the type of the alias if it's not the same
+QualType DeclarationType = AliasVar->getType();
+if (!DeclarationType.isNull() && DeclarationType->isReferenceType())
+  DeclarationType = DeclarationType.getNonReferenceType();
+if (Descriptor.ElemType.isNull() || DeclarationType.isNull() ||
+!Context->hasSameUnqualifiedType(DeclarationType, Descriptor.ElemType))
+  Descriptor.ElemType = AliasVar->getType();
+
 AliasVarIsRef = AliasVar->getType()->isReferenceType();
 
 // We keep along the entire DeclStmt to keep the correct range here.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D22069: clang-tidy modernize-loop-convert: preserve type of alias declaration (bug 28341)

2016-07-07 Thread Matthias Gehre via cfe-commits
mgehre added inline comments.


Comment at: clang-tidy/modernize/LoopConvertCheck.cpp:525
@@ +524,3 @@
+  DeclarationType = DeclarationType.getNonReferenceType();
+if (Descriptor.ElemType.isNull() || DeclarationType.isNull() ||
+!Context->hasSameUnqualifiedType(DeclarationType, Descriptor.ElemType))

alexfh wrote:
> 1. Can the `AliasVar->getType().isNull()` condition be true?
> 2. If it can, consider `!Descriptor.ElemType.isNull().isNull()` and 
> `AliasVar->getType().isNull()`. In this case setting `Descriptor.ElemType` to 
> `AliasVar->getType()` (which is null) doesn't make much sense.
> 
> I'd probably just wrap the added code in `if (!AliasVar->getType().isNull())`.
Thanks for you fast review.

I copied the block from isAliasDecl(). I don't see any reason why the types can 
be Null, but I'm also not an expert in llvm.

When would a VarDecl have no type? Maybe I should put an assert instead?


http://reviews.llvm.org/D22069



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


[PATCH] D24888: [clang-tidy] Use [[clang::suppress]] with cppcoreguidelines-pro-type-reinterpret-cast

2016-10-20 Thread Matthias Gehre via cfe-commits
mgehre added inline comments.



Comment at: clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp:25
 
-  Finder->addMatcher(cxxReinterpretCastExpr().bind("cast"), this);
+  std::vector Rules{"type", "type.1", 
"cppcoreguidelines-pro-type-reinterpret-cast"};
+  
Finder->addMatcher(cxxReinterpretCastExpr(unless(isSuppressed(Rules))).bind("cast"),
 this);

aaron.ballman wrote:
> malcolm.parsons wrote:
> > aaron.ballman wrote:
> > > mgehre wrote:
> > > > aaron.ballman wrote:
> > > > > Hmm, it seems like this is boilerplate we are going to want for every 
> > > > > rule, and that it's pretty easy to not get this right (for instance, 
> > > > > if you change the way the check is spelled, you have to remember to 
> > > > > update this as well). Could this actually be handled more 
> > > > > transparently, by gathering this information when the check is 
> > > > > registered and exposing it to the check?
> > > > > 
> > > > > The checks would still need to use `unless(isSuppressed(Rules))` in 
> > > > > some form, but I am thinking that it would be more convenient if we 
> > > > > could do: 
> > > > > `Finder->addMatcher(cxxReinterpretCastExpr(unlessSuppressed(*this)).bind("cast"),
> > > > >  this);`
> > > > I see multiple ways on how to integrate that into clang-tidy:
> > > > 1) Add something like you proposed to each matcher of each check
> > > > 2) Change (or add overload of)
> > > > ```
> > > >  DiagnosticBuilder diag(SourceLocation Loc, StringRef Description,
> > > >  DiagnosticIDs::Level Level = 
> > > > DiagnosticIDs::Warning);
> > > > ```
> > > > to add a AST node as parameter and make the SourceLocation optional. 
> > > > Most checks anyhow
> > > > call this like diag(E->getLoc(), ""), and then they would do 
> > > > diag(E, "...").
> > > > Diag then would check from the that AST node upwards to see if it finds 
> > > > a matching [[suppress]] attribute
> > > > 
> > > > 3) Change the RecursiveASTVistor that drives the AST Matches to prune 
> > > > certain matchers from the list of to-be-evaluated matchers
> > > > for all AST subtrees that are below a certain [[suppress]] attribute. 
> > > > (This is based on how I image that the AST matchers work)
> > > Ideally, I would like to see this attribute used to suppress Clang 
> > > diagnostics as well, however. So while I think Option 2 is better suited 
> > > to that future direction, it's still not ideal because all instances of 
> > > diag() need to be updated to take advantage. Options 1 and 3 are 
> > > basically limited to clang-tidy use.
> > > 
> > > I wonder if there's a way to modify the diagnostic builder to 
> > > transparently handle this without requiring modifying all of the call 
> > > sites?
> > clang-tidy reports how many warnings were suppressed by NOLINT comments.
> > I'd expect the number of warnings suppressed by [[clang::suppress]] to be 
> > included in the count.
> > Handling suppressions in the matchers or visitors would prevent this.
> As would handling the suppression transparently within the diagnostic engine 
> itself.
If there is a way to turn a SourceLocation into a ASTNode, diag() could handle 
this transparently (do you know how?). I would still add an overload of diag  
that takes an AST node as a performance optimization, because I imagine that 
going from SourceLocation to ASTNode would be a costly operation.
I can prototype that approach, if you like.



Comment at: clang-tidy/cppcoreguidelines/Suppression.h:59
+ anyOf(hasAncestor(attributedStmt(hasSuppressAttr(Rules))),
+   hasAncestor(decl(hasAttrs(), hasSuppressAttr(Rules)
+  .matches(Node, Finder, Builder);

aaron.ballman wrote:
> mgehre wrote:
> > aaron.ballman wrote:
> > > Why is the check for `hasAttrs` required?
> > > 
> > > Also, this use of `hasAncestor()` makes this expensive to use, and that 
> > > expense may be hidden from the caller. Is there a way to structure this 
> > > so that we don't need to walk the entire ancestor tree?
> > hasAttr() is needed here, because inside of hasSuppressAttr(), we call 
> > getAttrs() which would assert if hasAttr() is false.
> > I cannot push hasAttr() into hasSuppressAttr(), because hasSuppressAttr() 
> > is a template getting either Decl or AttributedStmt,
> > and AttributedStmt does not have an hasAttr() method.
> I believe that `getSpecificAttr` should be resilient to no attributes being 
> present (since it also has to handle the case there are no attributes of the 
> specific type, so no attributes at all is simply a degenerate case), and so 
> the check for `hasAttrs()` should be redundant.
Decl::getAttrs() will assert if called on a Decl where hasAttrs() is false, see
http://clang.llvm.org/doxygen/DeclBase_8cpp_source.html#l00741


https://reviews.llvm.org/D24888



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org

[PATCH] D24886: Add [[clang::suppress(rule, ...)]] attribute

2016-10-23 Thread Matthias Gehre via cfe-commits
mgehre added inline comments.



Comment at: include/clang/Basic/AttrDocs.td:2509
+to suppress specific clang-tidy warnings. They can be attached to a scope,
+statement or type. The ``[[gsl::suppress]]`` is an alias of 
``[[clang::suppress]]``
+which is intended to be used for suppressing rules of the C++ Core Guidelines_

aaron.ballman wrote:
> This statement does not match the test cases -- it does not appear to be 
> possible to attach the attribute to a type.
It is true that you cannot attach the attribute to an existing type during 
declaration of a variable,
but the attribute can be attached when declaring a new type. (See line 22 of 
the test case, where the attribute is attached to the union type U)
I would propose to says "type declaration" instead of "type", ok?



https://reviews.llvm.org/D24886



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


[PATCH] D26125: [clang-tidy] Fixed else-after-return warning in cascade if statement

2016-10-30 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

With this fix, is there still a warning on the following code?

  if(b) {
 ...
 if(c)
  return;
 else
  doSomething()
 ...
  }

I would expect that the check still warns on it.


https://reviews.llvm.org/D26125



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


Re: [PATCH] D22476: [AST] Make MemberExpr non-dependent according to core issue 224

2016-08-09 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

ping


https://reviews.llvm.org/D22476



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


Re: [PATCH] D22587: [ASTContext] Fix part of DR224 for nontype template arguments

2016-08-09 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

ping


https://reviews.llvm.org/D22587



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


Re: [PATCH] D15031: CFG: Add CFGElement for automatic variables that leave the scope

2016-04-03 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

Thank you very much for your review. I'm sorry that I'm currently quite busy, 
but I will find some time to answer at the end of this week.


http://reviews.llvm.org/D15031



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


Re: [PATCH] D15031: CFG: Add CFGElement for automatic variables that leave the scope

2016-04-06 Thread Matthias Gehre via cfe-commits
mgehre added inline comments.


Comment at: include/clang/Analysis/CFG.h:170
@@ -168,1 +169,3 @@
 
+class CFGAutomaticObjLeavesScope : public CFGElement {
+public:

rsmith wrote:
> What is this intended to model? There seem to be a few options here:
> 
>  1) The point at which the destructor would run if the object had a 
> non-trivial destructor
>  2) The point at which the storage duration for the underlying storage ends
>  3) The point at which the lifetime of the object ends
> 
> Note that these are all different -- for an object with a non-trivial 
> destructor, (1) and (3) are the same and for any other object (2) and (3) are 
> the same; (2) occurs after all destructors for the scope have run.
> 
> This matters for cases like:
> 
>   void f() {
> struct A { int *p; ~A() { *p = 0; } } a;
> int n;
> a.p = &n;
>   }
> 
> Here, the lifetime of `n` would end before the lifetime of `a` if `n` had a 
> non-trivial destructor. If `n`s lifetime actually ended there, this code 
> would have undefined behavior. But because the destruction of `n` is trivial, 
> the lifetime of `n` instead ends when its storage duration ends, which is 
> *after* `A`'s destructor runs, so the code is valid.
> 
> Please add a comment to this class to describe what it means.
The intend is to show the point after which it is undefined behavior to refer 
to an object, i.e.
   3. The point at which the lifetime of the object ends
I will add a comment to clarify this. I propose to rename the class to 
"CFGLifetimeEnds", okay?


Comment at: include/clang/Analysis/CFG.h:728
@@ +727,3 @@
+
+  // Scope leaving must be performed in reversed order. So insertion is in two
+  // steps. First we prepare space for some number of elements, then we insert

rsmith wrote:
> Why must reverse order be used? It's not possible for the effects of these 
> operations to interact with each other, is it? At least according to the C++ 
> standard, the "end of storage duration" effects all occur simultaneously.
The order is important as you showed in your example above. The liftetime 
checker should be able to detect the undefined behavior in

```
struct B { B() {}; int n; };
void f() {
  struct A {B *p; ~A() { b->n = 0; } } a;
  B b;
  a.p = &b;
}
```


http://reviews.llvm.org/D15031



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


Re: [PATCH] D15031: CFG: Add CFGElement for automatic variables that leave the scope

2016-04-07 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

By the way, is there a tool to generate parts of the test based on clang 
output, i.e.
something that will prefix the output of clang with "CHECK: " and "CHECK-NEXT:" 
so I can copy-and-paste
it into my test file?


http://reviews.llvm.org/D15031



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


Re: [PATCH] D15031: CFG: Add CFGElement for automatic variables that leave the scope

2016-04-07 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 52959.
mgehre added a comment.

Update for review comments

- Change name from ObjLeavesScope to LifetimeEnds
- Make sure that trivially destructible objects end their lifetime after 
non-trivial destructible objects
- Add test
- Add analyzer option to enable LifetimeEnds CFG entries (disabled by default)

Note that AddImplicitDtors is mutally exclusive with AddLifetime (may be 
changed by a later patch)


http://reviews.llvm.org/D15031

Files:
  include/clang/Analysis/AnalysisContext.h
  include/clang/Analysis/CFG.h
  include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
  lib/Analysis/AnalysisDeclContext.cpp
  lib/Analysis/CFG.cpp
  lib/StaticAnalyzer/Core/AnalysisManager.cpp
  lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/PathDiagnostic.cpp
  test/Analysis/analyzer-config.c
  test/Analysis/analyzer-config.cpp
  test/Analysis/lifetime-cfg-output.cpp

Index: test/Analysis/lifetime-cfg-output.cpp
===
--- /dev/null
+++ test/Analysis/lifetime-cfg-output.cpp
@@ -0,0 +1,673 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-lifetime=true -analyzer-config cfg-implicit-dtors=false %s > %t 2>&1
+// RUN: FileCheck --input-file=%t %s
+
+extern bool UV;
+class A {
+public:
+// CHECK:   [B2 (ENTRY)]
+// CHECK-NEXT:Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1: true
+// CHECK-NEXT:2: UV
+// CHECK-NEXT:3: [B1.2] = [B1.1]
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (1): B1
+A() { 
+UV = true;
+}
+// CHECK:   [B3 (ENTRY)]
+// CHECK-NEXT:Succs (1): B2
+// CHECK:   [B1]
+// CHECK-NEXT:1: 0
+// CHECK-NEXT:2: this
+// CHECK-NEXT:3: [B1.2]->p
+// CHECK-NEXT:4: [B1.3] (ImplicitCastExpr, LValueToRValue, int *)
+// CHECK-NEXT:5: *[B1.4]
+// CHECK-NEXT:6: [B1.5] = [B1.1]
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B2]
+// CHECK-NEXT:1: this
+// CHECK-NEXT:2: [B2.1]->p
+// CHECK-NEXT:3: [B2.2] (ImplicitCastExpr, LValueToRValue, int *)
+// CHECK-NEXT:4: [B2.3] (ImplicitCastExpr, PointerToBoolean, _Bool)
+// CHECK-NEXT:T: if [B2.4]
+// CHECK-NEXT:Preds (1): B3
+// CHECK-NEXT:Succs (2): B1 B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (2): B1 B2
+~A() {
+if(p)
+*p = 0;
+}
+// CHECK:   [B2 (ENTRY)]
+// CHECK-NEXT:Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1: 1
+// CHECK-NEXT:2: return [B1.1];
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (1): B1
+operator int() const { return 1; }
+int* p;
+};
+
+// CHECK:   [B2 (ENTRY)]
+// CHECK-NEXT:Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1:  (CXXConstructExpr, class A)
+// CHECK-NEXT:2: A a;
+// CHECK-NEXT:3: a
+// CHECK-NEXT:4: [B1.3] (ImplicitCastExpr, NoOp, const class A)
+// CHECK-NEXT:5: const A &b = a;
+// CHECK-NEXT:6: A() (CXXConstructExpr, class A)
+// CHECK-NEXT:7: [B1.6] (BindTemporary)
+// CHECK-NEXT:8: [B1.7] (ImplicitCastExpr, NoOp, const class A)
+// CHECK-NEXT:9: [B1.8]
+// CHECK-NEXT:   10: const A &c = A();
+// CHECK-NEXT:   11: [B1.10] (Lifetime ends)
+// CHECK-NEXT:   12: [B1.2] (Lifetime ends)
+// CHECK-NEXT:   13: [B1.5] (Lifetime ends)
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (1): B1
+void test_const_ref() {
+  A a;
+  const A& b = a;
+  const A& c = A();
+}
+
+// CHECK:  [B2 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1:  (CXXConstructExpr, class A [2])
+// CHECK-NEXT:2: A a[2];
+// CHECK-NEXT:3:  (CXXConstructExpr, class A [0])
+// CHECK-NEXT:4: A b[0];
+// lifetime of a ends when its destructors are run
+// CHECK-NEXT:5: [B1.2] (Lifetime ends)
+// lifetime of b ends when its storage duration ends
+// CHECK-NEXT:6: [B1.4] (Lifetime ends)
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:  [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void test_array() {
+  A a[2];
+  A b[0];
+}
+
+// CHECK:  [B2 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1:  (CXXConstructExpr, class A)
+// CHECK-NEXT:2: A a;
+// CHECK-NEXT:3:  (CXXConstructExpr, class A)
+// CHECK-NEXT:4: A c;
+// CHECK-NEXT:5:  (CXXConstructExpr, class A)
+// CHECK-NEXT:6: A d;
+// CHECK-NEXT:7: [B1.6] (Lifetime ends)
+// CHECK-NEXT:8: [B1.4] (Lifetime ends)
+// CHECK-NEXT:9:  (CXXConstructExpr, class A)
+// CHECK-NEXT:   10: A b;
+// CHECK-NEXT:   11: [B1.10] (Lifetime ends)
+// CHECK-NEXT:   12: [B1.2] (Lifetime ends)
+// CHECK-NEXT:Pred

Re: [PATCH] D15031: CFG: Add CFGElement for automatic variables that leave the scope

2016-04-08 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 53092.
mgehre added a comment.

Fix assert in LocalScope::const_iterator::distance when using goto to jump over 
trivially constructable variable declarations
Added two test cases for this


http://reviews.llvm.org/D15031

Files:
  include/clang/Analysis/AnalysisContext.h
  include/clang/Analysis/CFG.h
  include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
  lib/Analysis/AnalysisDeclContext.cpp
  lib/Analysis/CFG.cpp
  lib/StaticAnalyzer/Core/AnalysisManager.cpp
  lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/PathDiagnostic.cpp
  test/Analysis/analyzer-config.c
  test/Analysis/analyzer-config.cpp
  test/Analysis/lifetime-cfg-output.cpp

Index: test/Analysis/lifetime-cfg-output.cpp
===
--- /dev/null
+++ test/Analysis/lifetime-cfg-output.cpp
@@ -0,0 +1,735 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-lifetime=true -analyzer-config cfg-implicit-dtors=false %s > %t 2>&1
+// RUN: FileCheck --input-file=%t %s
+
+extern bool UV;
+class A {
+public:
+// CHECK:   [B2 (ENTRY)]
+// CHECK-NEXT:Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1: true
+// CHECK-NEXT:2: UV
+// CHECK-NEXT:3: [B1.2] = [B1.1]
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (1): B1
+A() { 
+UV = true;
+}
+// CHECK:   [B3 (ENTRY)]
+// CHECK-NEXT:Succs (1): B2
+// CHECK:   [B1]
+// CHECK-NEXT:1: 0
+// CHECK-NEXT:2: this
+// CHECK-NEXT:3: [B1.2]->p
+// CHECK-NEXT:4: [B1.3] (ImplicitCastExpr, LValueToRValue, int *)
+// CHECK-NEXT:5: *[B1.4]
+// CHECK-NEXT:6: [B1.5] = [B1.1]
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B2]
+// CHECK-NEXT:1: this
+// CHECK-NEXT:2: [B2.1]->p
+// CHECK-NEXT:3: [B2.2] (ImplicitCastExpr, LValueToRValue, int *)
+// CHECK-NEXT:4: [B2.3] (ImplicitCastExpr, PointerToBoolean, _Bool)
+// CHECK-NEXT:T: if [B2.4]
+// CHECK-NEXT:Preds (1): B3
+// CHECK-NEXT:Succs (2): B1 B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (2): B1 B2
+~A() {
+if(p)
+*p = 0;
+}
+// CHECK:   [B2 (ENTRY)]
+// CHECK-NEXT:Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1: 1
+// CHECK-NEXT:2: return [B1.1];
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (1): B1
+operator int() const { return 1; }
+int* p;
+};
+
+// CHECK:   [B2 (ENTRY)]
+// CHECK-NEXT:Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1:  (CXXConstructExpr, class A)
+// CHECK-NEXT:2: A a;
+// CHECK-NEXT:3: a
+// CHECK-NEXT:4: [B1.3] (ImplicitCastExpr, NoOp, const class A)
+// CHECK-NEXT:5: const A &b = a;
+// CHECK-NEXT:6: A() (CXXConstructExpr, class A)
+// CHECK-NEXT:7: [B1.6] (BindTemporary)
+// CHECK-NEXT:8: [B1.7] (ImplicitCastExpr, NoOp, const class A)
+// CHECK-NEXT:9: [B1.8]
+// CHECK-NEXT:   10: const A &c = A();
+// CHECK-NEXT:   11: [B1.10] (Lifetime ends)
+// CHECK-NEXT:   12: [B1.2] (Lifetime ends)
+// CHECK-NEXT:   13: [B1.5] (Lifetime ends)
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (1): B1
+void test_const_ref() {
+  A a;
+  const A& b = a;
+  const A& c = A();
+}
+
+// CHECK:  [B2 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1:  (CXXConstructExpr, class A [2])
+// CHECK-NEXT:2: A a[2];
+// CHECK-NEXT:3:  (CXXConstructExpr, class A [0])
+// CHECK-NEXT:4: A b[0];
+// lifetime of a ends when its destructors are run
+// CHECK-NEXT:5: [B1.2] (Lifetime ends)
+// lifetime of b ends when its storage duration ends
+// CHECK-NEXT:6: [B1.4] (Lifetime ends)
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:  [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void test_array() {
+  A a[2];
+  A b[0];
+}
+
+// CHECK:  [B2 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1:  (CXXConstructExpr, class A)
+// CHECK-NEXT:2: A a;
+// CHECK-NEXT:3:  (CXXConstructExpr, class A)
+// CHECK-NEXT:4: A c;
+// CHECK-NEXT:5:  (CXXConstructExpr, class A)
+// CHECK-NEXT:6: A d;
+// CHECK-NEXT:7: [B1.6] (Lifetime ends)
+// CHECK-NEXT:8: [B1.4] (Lifetime ends)
+// CHECK-NEXT:9:  (CXXConstructExpr, class A)
+// CHECK-NEXT:   10: A b;
+// CHECK-NEXT:   11: [B1.10] (Lifetime ends)
+// CHECK-NEXT:   12: [B1.2] (Lifetime ends)
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:  [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void test_scope() {
+  A a;
+  { A c;
+A d;
+  }
+  A b;
+}
+
+// CHECK:  [B4 (ENTRY)]
+// CHECK-NEXT:   Su

Re: [PATCH] D15032: [clang-tidy] new checker cppcoreguidelines-pro-lifetime

2016-04-08 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 53097.
mgehre added a comment.

Update for renaming in http://reviews.llvm.org/D15031


http://reviews.llvm.org/D15032

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProLifetimeCheck.cpp
  clang-tidy/cppcoreguidelines/ProLifetimeCheck.h
  clang-tidy/cppcoreguidelines/ProLifetimeVisitor.cpp
  clang-tidy/cppcoreguidelines/ProLifetimeVisitor.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-lifetime.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-lifetime-psets.cpp
  test/clang-tidy/cppcoreguidelines-pro-lifetime.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-lifetime.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-lifetime.cpp
@@ -0,0 +1,87 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-lifetime %t -- -config="{CheckOptions: [{key: cppcoreguidelines-pro-lifetime.Debug, value: 1}]}" -- -std=c++11
+
+struct S {
+  ~S();
+  int m;
+  int f();
+};
+
+void deref_uninitialized() {
+  int *p;
+  *p = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: dereferencing a dangling pointer [cppcoreguidelines-pro-lifetime]
+  // CHECK-MESSAGES: :[[@LINE-3]]:8: note: it became invalid because was never initialized here
+}
+
+void deref_nullptr() {
+  int *q = nullptr;
+  *q = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: dereferencing a null pointer
+}
+
+void ref_leaves_scope() {
+  int *p;
+  {
+int i = 0;
+p = &i;
+*p = 2; // OK
+  }
+  *p = 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: dereferencing a dangling pointer
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: note: it became invalid because the pointee i left the scope here
+}
+
+void ref_to_member_leaves_scope_call() {
+  S *p;
+  {
+S s;
+p = &s;
+p->f(); // OK
+  }
+  p->f();
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: dereferencing a dangling pointer
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: note: it became invalid because the pointee s left the scope here
+  int i = p->m;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: dereferencing a dangling pointer
+  // CHECK-MESSAGES: :[[@LINE-6]]:3: note: it became invalid because the pointee s left the scope here
+  p->m = 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: dereferencing a dangling pointer
+  // CHECK-MESSAGES: :[[@LINE-9]]:3: note: it became invalid because the pointee s left the scope here
+}
+
+// No Pointer involved, thus not checked
+void ignore_access_on_non_ref_ptr() {
+  S s;
+  s.m = 3;
+  s.f();
+}
+
+// Note: the messages below are for the template instantiation in instantiate_ref_leaves_scope_template
+// The checker only checks instantiations
+template
+void ref_leaves_scope_template() {
+  T p;
+  {
+int i = 0;
+p = &i;
+*p = 2; // OK
+  }
+  *p = 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: dereferencing a dangling pointer
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: note: it became invalid because the pointee i left the scope here
+}
+
+void instantiate_ref_leaves_scope_template() {
+  ref_leaves_scope_template();
+}
+
+int global_i = 4;
+int *global_init_p = &global_i; // OK
+int *global_uninit_p;
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: the pset of global_uninit_p must be a subset of {(static), (null)}, but is {(invalid)}
+int *global_null_p = nullptr; // OK
+
+void uninitialized_static() {
+  static int* p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: the pset of p must be a subset of {(static), (null)}, but is {(invalid)}
+}
Index: test/clang-tidy/cppcoreguidelines-pro-lifetime-psets.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-lifetime-psets.cpp
@@ -0,0 +1,512 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-lifetime %t -- -config="{CheckOptions: [{key: cppcoreguidelines-pro-lifetime.Debug, value: 1}]}" -- -std=c++11
+
+// TODO:
+// lifetime annotations
+// lambda
+// function calls
+
+template
+void clang_analyzer_pset(const T&);
+
+int rand();
+
+struct S {
+  ~S();
+  int m;
+  void f() {
+int* p = &m; // pset becomes m, not *this
+clang_analyzer_pset(p);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pset(p) = {m}
+  }
+};
+
+struct D : public S {
+  ~D();
+};
+
+void pointer_exprs() {
+  int *p;
+  clang_analyzer_pset(p);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pset(p) = {(invalid)} [cppcoreguidelines-pro-lifetime]
+  int *q = nullptr;
+  clang_analyzer_pset(q);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pset(q) = {(null)}
+  int *q2 = 0;
+  clang_analyzer_pset(q2);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pset(q2) = {(null)}
+  S s;
+  p = &s.m;
+  clang_analyzer_pset(p);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pset(p) = {s}
+  int a[2];
+  p = &a[0];
+  clang_analyzer_pset(p);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: pset(p) = {a}
+
+  D d;
+  S* ps = &d; // Ig

[PATCH] D18914: [clang-tidy] new readability-redundant-inline

2016-04-08 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added reviewers: sbenza, bkramer, aaron.ballman, alexfh.
mgehre added a subscriber: cfe-commits.

This check flags redundant 'inline' specifiers.
It flags 'inline' on member functions defined inside a class definition
like
.. code-block:: c++

  struct S {
inline int f() {
  return 0;
}
  };

and 'inline' specifiers on functions that are also declared 'constexpr'.

http://reviews.llvm.org/D18914

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tidy/readability/RedundantInlineCheck.cpp
  clang-tidy/readability/RedundantInlineCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-redundant-inline.rst
  test/clang-tidy/readability-redundant-inline.cpp

Index: test/clang-tidy/readability-redundant-inline.cpp
===
--- /dev/null
+++ test/clang-tidy/readability-redundant-inline.cpp
@@ -0,0 +1,67 @@
+// RUN: %check_clang_tidy %s readability-redundant-inline %t
+
+struct S {
+  inline int f1() {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because method body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  int f1()
+return 0;
+  }
+  inline int f2(); // OK
+  
+  inline constexpr int f3() {
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'inline' is redundant because 'constexpr' implies 'inline' [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  constexpr int f3()
+return 0;
+  }
+  static inline constexpr int f4() {
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'inline' is redundant because 'constexpr' implies 'inline'
+// CHECK-FIXES: {{^}}  static constexpr int f4()
+return 0;
+  }
+  
+  static inline int f5();
+
+  static inline int f6() {
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  static int f6()
+return 0;
+  }
+
+  inline friend int f7() {
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'inline' is redundant because function body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  friend int f7()
+  return 0;
+  }
+
+  inline friend int f8(); // OK
+};
+
+class S2 {
+  inline int f1() {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  int f1()
+return 0;
+  }
+};
+
+inline int S::f2() { // OK
+  return 0;
+}
+
+inline int S::f5() { // OK
+  return 0;
+}
+
+inline int f3() { // OK
+  return 0;
+}
+
+inline constexpr int f4() {
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 'inline' is redundant because 'constexpr' implies 'inline'
+// CHECK-FIXES: {{^}}constexpr int f4()
+  return 1;
+}
+
+constexpr int f5() { // OK
+  return 1;
+}
\ No newline at end of file
Index: docs/clang-tidy/checks/readability-redundant-inline.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/readability-redundant-inline.rst
@@ -0,0 +1,16 @@
+.. title:: clang-tidy - readability-redundant-inline
+
+readability-redundant-inline
+
+
+This check flags redundant 'inline' specifiers.
+It flags 'inline' on member functions defined inside a class definition like
+.. code-block:: c++
+
+  struct S {
+inline int f() {
+	  return 0;
+	}
+  };
+
+and 'inline' specifiers on functions that are also declared 'constexpr'.
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -105,6 +105,7 @@
readability-inconsistent-declaration-parameter-name
readability-named-parameter
readability-redundant-control-flow
+   readability-redundant-inline
readability-redundant-smartptr-get
readability-redundant-string-cstr
readability-redundant-string-init
Index: clang-tidy/readability/RedundantInlineCheck.h
===
--- /dev/null
+++ clang-tidy/readability/RedundantInlineCheck.h
@@ -0,0 +1,35 @@
+//===--- RedundantInlineCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_INLINE_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_REDUNDANT_INLINE_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// Flags redundant 'inline' when used on a method with inline body or on a constexpr function.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability-redundan

Re: [PATCH] D18914: [clang-tidy] new readability-redundant-inline

2016-04-09 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 53118.
mgehre added a comment.

Update for review comments


http://reviews.llvm.org/D18914

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tidy/readability/RedundantInlineCheck.cpp
  clang-tidy/readability/RedundantInlineCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-redundant-inline.rst
  test/clang-tidy/readability-redundant-inline.cpp

Index: test/clang-tidy/readability-redundant-inline.cpp
===
--- /dev/null
+++ test/clang-tidy/readability-redundant-inline.cpp
@@ -0,0 +1,67 @@
+// RUN: %check_clang_tidy %s readability-redundant-inline %t
+
+struct S {
+  inline int f1() {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because method body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  int f1()
+return 0;
+  }
+  inline int f2(); // OK
+  
+  inline constexpr int f3() {
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'inline' is redundant because 'constexpr' implies 'inline' [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  constexpr int f3()
+return 0;
+  }
+  static inline constexpr int f4() {
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'inline' is redundant because 'constexpr' implies 'inline'
+// CHECK-FIXES: {{^}}  static constexpr int f4()
+return 0;
+  }
+  
+  static inline int f5();
+
+  static inline int f6() {
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  static int f6()
+return 0;
+  }
+
+  inline friend int f7() {
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'inline' is redundant because function body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  friend int f7()
+  return 0;
+  }
+
+  inline friend int f8(); // OK
+};
+
+class S2 {
+  inline int f1() {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  int f1()
+return 0;
+  }
+};
+
+inline int S::f2() { // OK
+  return 0;
+}
+
+inline int S::f5() { // OK
+  return 0;
+}
+
+inline int f3() { // OK
+  return 0;
+}
+
+inline constexpr int f4() {
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 'inline' is redundant because 'constexpr' implies 'inline'
+// CHECK-FIXES: {{^}}constexpr int f4()
+  return 1;
+}
+
+constexpr int f5() { // OK
+  return 1;
+}
\ No newline at end of file
Index: docs/clang-tidy/checks/readability-redundant-inline.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/readability-redundant-inline.rst
@@ -0,0 +1,16 @@
+.. title:: clang-tidy - readability-redundant-inline
+
+readability-redundant-inline
+
+
+This check flags redundant ``inline`` specifiers.
+It flags ``inline`` on member functions defined inside a class definition like
+.. code-block:: c++
+
+  struct S {
+inline int f() {
+	  return 0;
+	}
+  };
+
+and ``inline`` specifiers on functions that are also declared ``constexpr``.
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -105,6 +105,7 @@
readability-inconsistent-declaration-parameter-name
readability-named-parameter
readability-redundant-control-flow
+   readability-redundant-inline
readability-redundant-smartptr-get
readability-redundant-string-cstr
readability-redundant-string-init
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -160,6 +160,12 @@
   Looks for procedures (functions returning no value) with ``return`` statements
   at the end of the function.  Such `return` statements are redundant.
 
+- New `readability-redundant-inline
+  `_ check
+
+  Looks for redundant ``inline`` specifiers which are implied by defining a body within a class definition
+  or by ``constexpr``.
+
 - New `readability-redundant-string-init
   `_ check
 
Index: clang-tidy/readability/RedundantInlineCheck.h
===
--- /dev/null
+++ clang-tidy/readability/RedundantInlineCheck.h
@@ -0,0 +1,35 @@
+//===--- RedundantInlineCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_T

Re: [PATCH] D18914: [clang-tidy] new readability-redundant-inline

2016-04-09 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

I'm thinking about extending the check to the following issue and would like to 
hear your opinion.
In C++, the following three code snippets all have identical meaning
1:

  struct S {
int f();
  };
  
  inline int S::f() {
   return 0;
  }

2:

  struct S {
inline int f();
  };
  int S::f() {
   return 0;
  }

3:

  struct S {
inline int f();
  };
  
  inline int S::f() {
   return 0;
  }

I personally think that 1) should be used, because late one could move the 
function definition to a source file (removing the inline) without having to 
touch
the class declaration. I can extend this patch to transform 2) and 3) into 1).

Alternatively, I could add an option to choose between 1), 2) or 3).
What do you think?


http://reviews.llvm.org/D18914



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


Re: [PATCH] D15031: CFG: Add CFGElement for automatic variables that leave the scope

2016-04-11 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 53261.
mgehre added a comment.

Remove unused CFGBuilder::prependLifetimeEndsWithTerminator


http://reviews.llvm.org/D15031

Files:
  include/clang/Analysis/AnalysisContext.h
  include/clang/Analysis/CFG.h
  include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
  lib/Analysis/AnalysisDeclContext.cpp
  lib/Analysis/CFG.cpp
  lib/StaticAnalyzer/Core/AnalysisManager.cpp
  lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/PathDiagnostic.cpp
  test/Analysis/analyzer-config.c
  test/Analysis/analyzer-config.cpp
  test/Analysis/lifetime-cfg-output.cpp

Index: test/Analysis/lifetime-cfg-output.cpp
===
--- /dev/null
+++ test/Analysis/lifetime-cfg-output.cpp
@@ -0,0 +1,735 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-lifetime=true -analyzer-config cfg-implicit-dtors=false %s > %t 2>&1
+// RUN: FileCheck --input-file=%t %s
+
+extern bool UV;
+class A {
+public:
+// CHECK:   [B2 (ENTRY)]
+// CHECK-NEXT:Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1: true
+// CHECK-NEXT:2: UV
+// CHECK-NEXT:3: [B1.2] = [B1.1]
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (1): B1
+A() { 
+UV = true;
+}
+// CHECK:   [B3 (ENTRY)]
+// CHECK-NEXT:Succs (1): B2
+// CHECK:   [B1]
+// CHECK-NEXT:1: 0
+// CHECK-NEXT:2: this
+// CHECK-NEXT:3: [B1.2]->p
+// CHECK-NEXT:4: [B1.3] (ImplicitCastExpr, LValueToRValue, int *)
+// CHECK-NEXT:5: *[B1.4]
+// CHECK-NEXT:6: [B1.5] = [B1.1]
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B2]
+// CHECK-NEXT:1: this
+// CHECK-NEXT:2: [B2.1]->p
+// CHECK-NEXT:3: [B2.2] (ImplicitCastExpr, LValueToRValue, int *)
+// CHECK-NEXT:4: [B2.3] (ImplicitCastExpr, PointerToBoolean, _Bool)
+// CHECK-NEXT:T: if [B2.4]
+// CHECK-NEXT:Preds (1): B3
+// CHECK-NEXT:Succs (2): B1 B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (2): B1 B2
+~A() {
+if(p)
+*p = 0;
+}
+// CHECK:   [B2 (ENTRY)]
+// CHECK-NEXT:Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1: 1
+// CHECK-NEXT:2: return [B1.1];
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (1): B1
+operator int() const { return 1; }
+int* p;
+};
+
+// CHECK:   [B2 (ENTRY)]
+// CHECK-NEXT:Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1:  (CXXConstructExpr, class A)
+// CHECK-NEXT:2: A a;
+// CHECK-NEXT:3: a
+// CHECK-NEXT:4: [B1.3] (ImplicitCastExpr, NoOp, const class A)
+// CHECK-NEXT:5: const A &b = a;
+// CHECK-NEXT:6: A() (CXXConstructExpr, class A)
+// CHECK-NEXT:7: [B1.6] (BindTemporary)
+// CHECK-NEXT:8: [B1.7] (ImplicitCastExpr, NoOp, const class A)
+// CHECK-NEXT:9: [B1.8]
+// CHECK-NEXT:   10: const A &c = A();
+// CHECK-NEXT:   11: [B1.10] (Lifetime ends)
+// CHECK-NEXT:   12: [B1.2] (Lifetime ends)
+// CHECK-NEXT:   13: [B1.5] (Lifetime ends)
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:   [B0 (EXIT)]
+// CHECK-NEXT:Preds (1): B1
+void test_const_ref() {
+  A a;
+  const A& b = a;
+  const A& c = A();
+}
+
+// CHECK:  [B2 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1:  (CXXConstructExpr, class A [2])
+// CHECK-NEXT:2: A a[2];
+// CHECK-NEXT:3:  (CXXConstructExpr, class A [0])
+// CHECK-NEXT:4: A b[0];
+// lifetime of a ends when its destructors are run
+// CHECK-NEXT:5: [B1.2] (Lifetime ends)
+// lifetime of b ends when its storage duration ends
+// CHECK-NEXT:6: [B1.4] (Lifetime ends)
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:  [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void test_array() {
+  A a[2];
+  A b[0];
+}
+
+// CHECK:  [B2 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B1
+// CHECK:   [B1]
+// CHECK-NEXT:1:  (CXXConstructExpr, class A)
+// CHECK-NEXT:2: A a;
+// CHECK-NEXT:3:  (CXXConstructExpr, class A)
+// CHECK-NEXT:4: A c;
+// CHECK-NEXT:5:  (CXXConstructExpr, class A)
+// CHECK-NEXT:6: A d;
+// CHECK-NEXT:7: [B1.6] (Lifetime ends)
+// CHECK-NEXT:8: [B1.4] (Lifetime ends)
+// CHECK-NEXT:9:  (CXXConstructExpr, class A)
+// CHECK-NEXT:   10: A b;
+// CHECK-NEXT:   11: [B1.10] (Lifetime ends)
+// CHECK-NEXT:   12: [B1.2] (Lifetime ends)
+// CHECK-NEXT:Preds (1): B2
+// CHECK-NEXT:Succs (1): B0
+// CHECK:  [B0 (EXIT)]
+// CHECK-NEXT:   Preds (1): B1
+void test_scope() {
+  A a;
+  { A c;
+A d;
+  }
+  A b;
+}
+
+// CHECK:  [B4 (ENTRY)]
+// CHECK-NEXT:   Succs (1): B3
+// CHECK:   [B1]
+// CHECK-NEXT:1:  (CXXConstructExpr, class A)
+// CHECK-NE

[PATCH] D18991: [ASTMatchers]: fix crash in hasReturnValue

2016-04-11 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added reviewers: klimek, alexfh.
mgehre added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

The crash was reproduced by the included test case. It was initially
found through a crash of clang-tidy's misc-misplaced-widening-cast
check.

http://reviews.llvm.org/D18991

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -5500,6 +5500,7 @@
   StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
   EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
   EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
+  EXPECT_FALSE(matches("void F() { return; }", RetVal));
 }
 
 } // end namespace ast_matchers
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -5015,6 +5015,8 @@
 ///   matching 'a + b'
 AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher, 
   InnerMatcher) {
+  if (!Node.getRetValue())
+return false;
   return InnerMatcher.matches(*Node.getRetValue(), Finder, Builder);
 }
 


Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -5500,6 +5500,7 @@
   StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
   EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
   EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
+  EXPECT_FALSE(matches("void F() { return; }", RetVal));
 }
 
 } // end namespace ast_matchers
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -5015,6 +5015,8 @@
 ///   matching 'a + b'
 AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher, 
   InnerMatcher) {
+  if (!Node.getRetValue())
+return false;
   return InnerMatcher.matches(*Node.getRetValue(), Finder, Builder);
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D18914: [clang-tidy] new readability-redundant-inline

2016-04-11 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 53315.
mgehre added a comment.

Update for review comments; simplified lexing, added proposed test case


http://reviews.llvm.org/D18914

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tidy/readability/RedundantInlineCheck.cpp
  clang-tidy/readability/RedundantInlineCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-redundant-inline.rst
  test/clang-tidy/readability-redundant-inline.cpp

Index: test/clang-tidy/readability-redundant-inline.cpp
===
--- /dev/null
+++ test/clang-tidy/readability-redundant-inline.cpp
@@ -0,0 +1,72 @@
+// RUN: %check_clang_tidy %s readability-redundant-inline %t
+
+struct S {
+  inline int f1() {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because method body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  int f1()
+return 0;
+  }
+  inline int f2(); // OK
+
+  inline constexpr int f3() {
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'inline' is redundant because 'constexpr' implies 'inline' [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  constexpr int f3()
+return 0;
+  }
+  static inline constexpr int f4() {
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'inline' is redundant because 'constexpr' implies 'inline'
+// CHECK-FIXES: {{^}}  static constexpr int f4()
+return 0;
+  }
+
+  static inline int f5();
+
+  static inline int f6() {
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  static int f6()
+return 0;
+  }
+
+  inline friend int f7() {
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'inline' is redundant because function body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  friend int f7()
+  return 0;
+  }
+
+  inline friend int f8(); // OK
+
+  template struct T{};
+  struct T inline f9() { return {}; }
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  struct T f9() { return {}; }
+};
+
+class S2 {
+  inline int f1() {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  int f1()
+return 0;
+  }
+};
+
+inline int S::f2() { // OK
+  return 0;
+}
+
+inline int S::f5() { // OK
+  return 0;
+}
+
+inline int f3() { // OK
+  return 0;
+}
+
+inline constexpr int f4() {
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 'inline' is redundant because 'constexpr' implies 'inline'
+// CHECK-FIXES: {{^}}constexpr int f4()
+  return 1;
+}
+
+constexpr int f5() { // OK
+  return 1;
+}
Index: docs/clang-tidy/checks/readability-redundant-inline.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/readability-redundant-inline.rst
@@ -0,0 +1,16 @@
+.. title:: clang-tidy - readability-redundant-inline
+
+readability-redundant-inline
+
+
+This check flags redundant ``inline`` specifiers.
+It flags ``inline`` on member functions defined inside a class definition like
+.. code-block:: c++
+
+  struct S {
+inline int f() {
+  return 0;
+}
+  };
+
+and ``inline`` specifiers on functions that are also declared ``constexpr``.
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -105,6 +105,7 @@
readability-inconsistent-declaration-parameter-name
readability-named-parameter
readability-redundant-control-flow
+   readability-redundant-inline
readability-redundant-smartptr-get
readability-redundant-string-cstr
readability-redundant-string-init
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -160,6 +160,12 @@
   Looks for procedures (functions returning no value) with ``return`` statements
   at the end of the function.  Such `return` statements are redundant.
 
+- New `readability-redundant-inline
+  `_ check
+
+  Looks for redundant ``inline`` specifiers which are implied by defining a body within a class definition
+  or by ``constexpr``.
+
 - New `readability-redundant-string-init
   `_ check
 
Index: clang-tidy/readability/RedundantInlineCheck.h
===
--- /dev/null
+++ clang-tidy/readability/RedundantInlineCheck.h
@@ -0,0 +1,35 @@
+//===--- RedundantInlineCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Comp

Re: [PATCH] D18914: [clang-tidy] new readability-redundant-inline

2016-04-11 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 53317.
mgehre added a comment.

Removed debug output


http://reviews.llvm.org/D18914

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tidy/readability/RedundantInlineCheck.cpp
  clang-tidy/readability/RedundantInlineCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-redundant-inline.rst
  test/clang-tidy/readability-redundant-inline.cpp

Index: test/clang-tidy/readability-redundant-inline.cpp
===
--- /dev/null
+++ test/clang-tidy/readability-redundant-inline.cpp
@@ -0,0 +1,72 @@
+// RUN: %check_clang_tidy %s readability-redundant-inline %t
+
+struct S {
+  inline int f1() {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because method body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  int f1()
+return 0;
+  }
+  inline int f2(); // OK
+
+  inline constexpr int f3() {
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'inline' is redundant because 'constexpr' implies 'inline' [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  constexpr int f3()
+return 0;
+  }
+  static inline constexpr int f4() {
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'inline' is redundant because 'constexpr' implies 'inline'
+// CHECK-FIXES: {{^}}  static constexpr int f4()
+return 0;
+  }
+
+  static inline int f5();
+
+  static inline int f6() {
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  static int f6()
+return 0;
+  }
+
+  inline friend int f7() {
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'inline' is redundant because function body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  friend int f7()
+  return 0;
+  }
+
+  inline friend int f8(); // OK
+
+  template struct T{};
+  struct T inline f9() { return {}; }
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  struct T f9() { return {}; }
+};
+
+class S2 {
+  inline int f1() {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  int f1()
+return 0;
+  }
+};
+
+inline int S::f2() { // OK
+  return 0;
+}
+
+inline int S::f5() { // OK
+  return 0;
+}
+
+inline int f3() { // OK
+  return 0;
+}
+
+inline constexpr int f4() {
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 'inline' is redundant because 'constexpr' implies 'inline'
+// CHECK-FIXES: {{^}}constexpr int f4()
+  return 1;
+}
+
+constexpr int f5() { // OK
+  return 1;
+}
Index: docs/clang-tidy/checks/readability-redundant-inline.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/readability-redundant-inline.rst
@@ -0,0 +1,16 @@
+.. title:: clang-tidy - readability-redundant-inline
+
+readability-redundant-inline
+
+
+This check flags redundant ``inline`` specifiers.
+It flags ``inline`` on member functions defined inside a class definition like
+.. code-block:: c++
+
+  struct S {
+inline int f() {
+  return 0;
+}
+  };
+
+and ``inline`` specifiers on functions that are also declared ``constexpr``.
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -105,6 +105,7 @@
readability-inconsistent-declaration-parameter-name
readability-named-parameter
readability-redundant-control-flow
+   readability-redundant-inline
readability-redundant-smartptr-get
readability-redundant-string-cstr
readability-redundant-string-init
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -160,6 +160,12 @@
   Looks for procedures (functions returning no value) with ``return`` statements
   at the end of the function.  Such `return` statements are redundant.
 
+- New `readability-redundant-inline
+  `_ check
+
+  Looks for redundant ``inline`` specifiers which are implied by defining a body within a class definition
+  or by ``constexpr``.
+
 - New `readability-redundant-string-init
   `_ check
 
Index: clang-tidy/readability/RedundantInlineCheck.h
===
--- /dev/null
+++ clang-tidy/readability/RedundantInlineCheck.h
@@ -0,0 +1,35 @@
+//===--- RedundantInlineCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distribute

[PATCH] D18993: [clang-tidy] fix readability-avoid-const-params-in-decls creating invalid code in fix-its

2016-04-11 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added reviewers: fowles, hokein, sbenza, alexfh.
mgehre added a subscriber: cfe-commits.

The Fix-Its for the added test cases were before:
-void F11(const unsigned int /*version*/);
+void F11(unsigned int int /*version*/);

-void F12(const bool b = true);
+void F12(_Bool true);

http://reviews.llvm.org/D18993

Files:
  clang-tidy/readability/AvoidConstParamsInDecls.cpp
  test/clang-tidy/readability-avoid-const-params-in-decls.cpp

Index: test/clang-tidy/readability-avoid-const-params-in-decls.cpp
===
--- test/clang-tidy/readability-avoid-const-params-in-decls.cpp
+++ test/clang-tidy/readability-avoid-const-params-in-decls.cpp
@@ -10,7 +10,7 @@
 
 void F2(const int *const i);
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
-// CHECK-FIXES: void F2(const int * i);
+// CHECK-FIXES: void F2(const int *i);
 
 void F3(int const i);
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
@@ -26,7 +26,7 @@
 
 void F6(const int *const);
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 1 is const-qualified
-// BUG(b/27584482): void F6(const int *);  should be produced
+// CHECK-FIXES: void F6(const int *);
 
 void F7(int, const int);
 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: parameter 2 is const-qualified
@@ -43,8 +43,15 @@
 
 void F10(const int *const *const long_name);
 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 'long_name'
-// CHECK-FIXES: void F10(const int *const * long_name);
+// CHECK-FIXES: void F10(const int *const *long_name);
 
+void F11(const unsigned int /*v*/);
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 1
+// CHECK-FIXES: void F11(unsigned int /*v*/);
+
+void F12(const bool b = true);
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 'b'
+// CHECK-FIXES: void F12(bool b = true);
 
 struct Foo {
   Foo(const int i);
Index: clang-tidy/readability/AvoidConstParamsInDecls.cpp
===
--- clang-tidy/readability/AvoidConstParamsInDecls.cpp
+++ clang-tidy/readability/AvoidConstParamsInDecls.cpp
@@ -28,7 +28,6 @@
 
 } // namespace
 
-
 void AvoidConstParamsInDecls::registerMatchers(MatchFinder *Finder) {
   const auto ConstParamDecl =
   parmVarDecl(hasType(qualType(isConstQualified(.bind("param");
@@ -38,16 +37,41 @@
  this);
 }
 
+// Re-lex the tokens to get precise location of last 'const'
+static Token ConstTok(CharSourceRange Range,
+  const MatchFinder::MatchResult &Result) {
+  const SourceManager &Sources = *Result.SourceManager;
+  std::pair LocInfo =
+  Sources.getDecomposedLoc(Range.getBegin());
+  StringRef File = Sources.getBufferData(LocInfo.first);
+  const char *TokenBegin = File.data() + LocInfo.second;
+  Lexer RawLexer(Sources.getLocForStartOfFile(LocInfo.first),
+ Result.Context->getLangOpts(), File.begin(), TokenBegin,
+ File.end());
+  Token Tok;
+  Token ConstTok;
+  while (!RawLexer.LexFromRawLexer(Tok)) {
+if (Sources.isBeforeInTranslationUnit(Range.getEnd(), Tok.getLocation()))
+  break;
+if (Tok.is(tok::raw_identifier)) {
+  IdentifierInfo &Info = Result.Context->Idents.get(StringRef(
+  Sources.getCharacterData(Tok.getLocation()), Tok.getLength()));
+  Tok.setIdentifierInfo(&Info);
+  Tok.setKind(Info.getTokenID());
+}
+if (Tok.is(tok::kw_const))
+  ConstTok = Tok;
+  }
+  return ConstTok;
+}
+
 void AvoidConstParamsInDecls::check(const MatchFinder::MatchResult &Result) {
   const auto *Func = Result.Nodes.getNodeAs("func");
   const auto *Param = Result.Nodes.getNodeAs("param");
 
-  QualType Type = Param->getType();
-  if (!Type.isLocalConstQualified())
+  if (!Param->getType().isLocalConstQualified())
 return;
 
-  Type.removeLocalConst();
-
   auto Diag = diag(Param->getLocStart(),
"parameter %0 is const-qualified in the function "
"declaration; const-qualification of parameters only has an "
@@ -62,8 +86,17 @@
   } else {
 Diag << Param;
   }
-  Diag << FixItHint::CreateReplacement(getTypeRange(*Param),
-   Type.getAsString());
+
+  CharSourceRange FileRange = Lexer::makeFileCharRange(
+  CharSourceRange::getTokenRange(getTypeRange(*Param)),
+  *Result.SourceManager, Result.Context->getLangOpts());
+
+  if (!FileRange.isValid())
+return;
+
+  Token Tok = ConstTok(FileRange, Result);
+  Diag << FixItHint::CreateRemoval(
+  CharSourceRange::getTokenRange(Tok.getLocation(), Tok.getLocation()));
 }
 
 } // namespace readability
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D18914: [clang-tidy] new readability-redundant-inline

2016-04-11 Thread Matthias Gehre via cfe-commits
mgehre added inline comments.


Comment at: test/clang-tidy/readability-redundant-inline.cpp:6
@@ +5,3 @@
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because 
method body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  int f1()
+return 0;

Personally, I never use "inline" to mean anything else than "multiple 
definitions can appear". I didn't know that
compilers still respected this.

Does that mean that the whole checker is useless?


http://reviews.llvm.org/D18914



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


r266043 - [ASTMatchers]: fix crash in hasReturnValue

2016-04-11 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Tue Apr 12 00:43:18 2016
New Revision: 266043

URL: http://llvm.org/viewvc/llvm-project?rev=266043&view=rev
Log:
[ASTMatchers]: fix crash in hasReturnValue

Summary:
The crash was reproduced by the included test case. It was initially
found through a crash of clang-tidy's misc-misplaced-widening-cast
check.

Reviewers: klimek, alexfh

Subscribers: cfe-commits, klimek

Differential Revision: http://reviews.llvm.org/D18991

Modified:
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=266043&r1=266042&r2=266043&view=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Tue Apr 12 00:43:18 2016
@@ -5013,9 +5013,11 @@ AST_MATCHER_P(Decl, hasAttr, attr::Kind,
 ///   matches 'return a + b'
 /// with binaryOperator()
 ///   matching 'a + b'
-AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher, 
+AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher,
   InnerMatcher) {
-  return InnerMatcher.matches(*Node.getRetValue(), Finder, Builder);
+  if (const auto *RetValue = Node.getRetValue())
+return InnerMatcher.matches(*RetValue, Finder, Builder);
+  return false;
 }
 
 

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp?rev=266043&r1=266042&r2=266043&view=diff
==
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp Tue Apr 12 00:43:18 2016
@@ -5500,6 +5500,7 @@ TEST(StatementMatcher, HasReturnValue) {
   StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
   EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
   EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
+  EXPECT_FALSE(matches("void F() { return; }", RetVal));
 }
 
 } // end namespace ast_matchers


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


Re: [PATCH] D18991: [ASTMatchers]: fix crash in hasReturnValue

2016-04-11 Thread Matthias Gehre via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL266043: [ASTMatchers]: fix crash in hasReturnValue (authored 
by mgehre).

Changed prior to commit:
  http://reviews.llvm.org/D18991?vs=53311&id=53367#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D18991

Files:
  cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
  cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp

Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -5500,6 +5500,7 @@
   StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
   EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
   EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
+  EXPECT_FALSE(matches("void F() { return; }", RetVal));
 }
 
 } // end namespace ast_matchers
Index: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
===
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
@@ -5013,9 +5013,11 @@
 ///   matches 'return a + b'
 /// with binaryOperator()
 ///   matching 'a + b'
-AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher, 
+AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher,
   InnerMatcher) {
-  return InnerMatcher.matches(*Node.getRetValue(), Finder, Builder);
+  if (const auto *RetValue = Node.getRetValue())
+return InnerMatcher.matches(*RetValue, Finder, Builder);
+  return false;
 }
 
 


Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -5500,6 +5500,7 @@
   StatementMatcher RetVal = returnStmt(hasReturnValue(binaryOperator()));
   EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal));
   EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal));
+  EXPECT_FALSE(matches("void F() { return; }", RetVal));
 }
 
 } // end namespace ast_matchers
Index: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
===
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
@@ -5013,9 +5013,11 @@
 ///   matches 'return a + b'
 /// with binaryOperator()
 ///   matching 'a + b'
-AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher, 
+AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher,
   InnerMatcher) {
-  return InnerMatcher.matches(*Node.getRetValue(), Finder, Builder);
+  if (const auto *RetValue = Node.getRetValue())
+return InnerMatcher.matches(*RetValue, Finder, Builder);
+  return false;
 }
 
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D18993: [clang-tidy] fix readability-avoid-const-params-in-decls creating invalid code in fix-its

2016-04-11 Thread Matthias Gehre via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL266044: [clang-tidy] fix 
readability-avoid-const-params-in-decls creating invalid… (authored by mgehre).

Changed prior to commit:
  http://reviews.llvm.org/D18993?vs=53322&id=53368#toc

Repository:
  rL LLVM

http://reviews.llvm.org/D18993

Files:
  clang-tools-extra/trunk/clang-tidy/readability/AvoidConstParamsInDecls.cpp
  
clang-tools-extra/trunk/test/clang-tidy/readability-avoid-const-params-in-decls.cpp

Index: clang-tools-extra/trunk/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
===
--- clang-tools-extra/trunk/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
+++ clang-tools-extra/trunk/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
@@ -10,7 +10,7 @@
 
 void F2(const int *const i);
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
-// CHECK-FIXES: void F2(const int * i);
+// CHECK-FIXES: void F2(const int *i);
 
 void F3(int const i);
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
@@ -26,7 +26,7 @@
 
 void F6(const int *const);
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 1 is const-qualified
-// BUG(b/27584482): void F6(const int *);  should be produced
+// CHECK-FIXES: void F6(const int *);
 
 void F7(int, const int);
 // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: parameter 2 is const-qualified
@@ -43,8 +43,15 @@
 
 void F10(const int *const *const long_name);
 // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 'long_name'
-// CHECK-FIXES: void F10(const int *const * long_name);
+// CHECK-FIXES: void F10(const int *const *long_name);
 
+void F11(const unsigned int /*v*/);
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 1
+// CHECK-FIXES: void F11(unsigned int /*v*/);
+
+void F12(const bool b = true);
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: parameter 'b'
+// CHECK-FIXES: void F12(bool b = true);
 
 struct Foo {
   Foo(const int i);
Index: clang-tools-extra/trunk/clang-tidy/readability/AvoidConstParamsInDecls.cpp
===
--- clang-tools-extra/trunk/clang-tidy/readability/AvoidConstParamsInDecls.cpp
+++ clang-tools-extra/trunk/clang-tidy/readability/AvoidConstParamsInDecls.cpp
@@ -28,7 +28,6 @@
 
 } // namespace
 
-
 void AvoidConstParamsInDecls::registerMatchers(MatchFinder *Finder) {
   const auto ConstParamDecl =
   parmVarDecl(hasType(qualType(isConstQualified(.bind("param");
@@ -38,16 +37,41 @@
  this);
 }
 
+// Re-lex the tokens to get precise location of last 'const'
+static Token ConstTok(CharSourceRange Range,
+  const MatchFinder::MatchResult &Result) {
+  const SourceManager &Sources = *Result.SourceManager;
+  std::pair LocInfo =
+  Sources.getDecomposedLoc(Range.getBegin());
+  StringRef File = Sources.getBufferData(LocInfo.first);
+  const char *TokenBegin = File.data() + LocInfo.second;
+  Lexer RawLexer(Sources.getLocForStartOfFile(LocInfo.first),
+ Result.Context->getLangOpts(), File.begin(), TokenBegin,
+ File.end());
+  Token Tok;
+  Token ConstTok;
+  while (!RawLexer.LexFromRawLexer(Tok)) {
+if (Sources.isBeforeInTranslationUnit(Range.getEnd(), Tok.getLocation()))
+  break;
+if (Tok.is(tok::raw_identifier)) {
+  IdentifierInfo &Info = Result.Context->Idents.get(StringRef(
+  Sources.getCharacterData(Tok.getLocation()), Tok.getLength()));
+  Tok.setIdentifierInfo(&Info);
+  Tok.setKind(Info.getTokenID());
+}
+if (Tok.is(tok::kw_const))
+  ConstTok = Tok;
+  }
+  return ConstTok;
+}
+
 void AvoidConstParamsInDecls::check(const MatchFinder::MatchResult &Result) {
   const auto *Func = Result.Nodes.getNodeAs("func");
   const auto *Param = Result.Nodes.getNodeAs("param");
 
-  QualType Type = Param->getType();
-  if (!Type.isLocalConstQualified())
+  if (!Param->getType().isLocalConstQualified())
 return;
 
-  Type.removeLocalConst();
-
   auto Diag = diag(Param->getLocStart(),
"parameter %0 is const-qualified in the function "
"declaration; const-qualification of parameters only has an "
@@ -62,8 +86,17 @@
   } else {
 Diag << Param;
   }
-  Diag << FixItHint::CreateReplacement(getTypeRange(*Param),
-   Type.getAsString());
+
+  CharSourceRange FileRange = Lexer::makeFileCharRange(
+  CharSourceRange::getTokenRange(getTypeRange(*Param)),
+  *Result.SourceManager, Result.Context->getLangOpts());
+
+  if (!FileRange.isValid())
+return;
+
+  Token Tok = ConstTok(FileRange, Result);
+  Diag << FixItHint::CreateRemoval(
+  CharSourceRange::getTokenRange(Tok.getLocation(), Tok.getLocation()));
 }
 
 } // namespace readability
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http:/

[clang-tools-extra] r266044 - [clang-tidy] fix readability-avoid-const-params-in-decls creating invalid code in fix-its

2016-04-11 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Tue Apr 12 00:45:13 2016
New Revision: 266044

URL: http://llvm.org/viewvc/llvm-project?rev=266044&view=rev
Log:
[clang-tidy] fix readability-avoid-const-params-in-decls creating invalid code 
in fix-its

Summary:
The Fix-Its for the added test cases were before:
-void F11(const unsigned int /*version*/);
+void F11(unsigned int int /*version*/);

-void F12(const bool b = true);
+void F12(_Bool true);

Reviewers: fowles, hokein, sbenza, alexfh

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D18993

Modified:
clang-tools-extra/trunk/clang-tidy/readability/AvoidConstParamsInDecls.cpp

clang-tools-extra/trunk/test/clang-tidy/readability-avoid-const-params-in-decls.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/readability/AvoidConstParamsInDecls.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/AvoidConstParamsInDecls.cpp?rev=266044&r1=266043&r2=266044&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/readability/AvoidConstParamsInDecls.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/readability/AvoidConstParamsInDecls.cpp 
Tue Apr 12 00:45:13 2016
@@ -28,7 +28,6 @@ SourceRange getTypeRange(const ParmVarDe
 
 } // namespace
 
-
 void AvoidConstParamsInDecls::registerMatchers(MatchFinder *Finder) {
   const auto ConstParamDecl =
   parmVarDecl(hasType(qualType(isConstQualified(.bind("param");
@@ -38,16 +37,41 @@ void AvoidConstParamsInDecls::registerMa
  this);
 }
 
+// Re-lex the tokens to get precise location of last 'const'
+static Token ConstTok(CharSourceRange Range,
+  const MatchFinder::MatchResult &Result) {
+  const SourceManager &Sources = *Result.SourceManager;
+  std::pair LocInfo =
+  Sources.getDecomposedLoc(Range.getBegin());
+  StringRef File = Sources.getBufferData(LocInfo.first);
+  const char *TokenBegin = File.data() + LocInfo.second;
+  Lexer RawLexer(Sources.getLocForStartOfFile(LocInfo.first),
+ Result.Context->getLangOpts(), File.begin(), TokenBegin,
+ File.end());
+  Token Tok;
+  Token ConstTok;
+  while (!RawLexer.LexFromRawLexer(Tok)) {
+if (Sources.isBeforeInTranslationUnit(Range.getEnd(), Tok.getLocation()))
+  break;
+if (Tok.is(tok::raw_identifier)) {
+  IdentifierInfo &Info = Result.Context->Idents.get(StringRef(
+  Sources.getCharacterData(Tok.getLocation()), Tok.getLength()));
+  Tok.setIdentifierInfo(&Info);
+  Tok.setKind(Info.getTokenID());
+}
+if (Tok.is(tok::kw_const))
+  ConstTok = Tok;
+  }
+  return ConstTok;
+}
+
 void AvoidConstParamsInDecls::check(const MatchFinder::MatchResult &Result) {
   const auto *Func = Result.Nodes.getNodeAs("func");
   const auto *Param = Result.Nodes.getNodeAs("param");
 
-  QualType Type = Param->getType();
-  if (!Type.isLocalConstQualified())
+  if (!Param->getType().isLocalConstQualified())
 return;
 
-  Type.removeLocalConst();
-
   auto Diag = diag(Param->getLocStart(),
"parameter %0 is const-qualified in the function "
"declaration; const-qualification of parameters only has an 
"
@@ -62,8 +86,17 @@ void AvoidConstParamsInDecls::check(cons
   } else {
 Diag << Param;
   }
-  Diag << FixItHint::CreateReplacement(getTypeRange(*Param),
-   Type.getAsString());
+
+  CharSourceRange FileRange = Lexer::makeFileCharRange(
+  CharSourceRange::getTokenRange(getTypeRange(*Param)),
+  *Result.SourceManager, Result.Context->getLangOpts());
+
+  if (!FileRange.isValid())
+return;
+
+  Token Tok = ConstTok(FileRange, Result);
+  Diag << FixItHint::CreateRemoval(
+  CharSourceRange::getTokenRange(Tok.getLocation(), Tok.getLocation()));
 }
 
 } // namespace readability

Modified: 
clang-tools-extra/trunk/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/readability-avoid-const-params-in-decls.cpp?rev=266044&r1=266043&r2=266044&view=diff
==
--- 
clang-tools-extra/trunk/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
 (original)
+++ 
clang-tools-extra/trunk/test/clang-tidy/readability-avoid-const-params-in-decls.cpp
 Tue Apr 12 00:45:13 2016
@@ -10,7 +10,7 @@ void F1(const int i);
 
 void F2(const int *const i);
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
-// CHECK-FIXES: void F2(const int * i);
+// CHECK-FIXES: void F2(const int *i);
 
 void F3(int const i);
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is const-qualified
@@ -26,7 +26,7 @@ void F5(const int);
 
 void F6(const int *const);
 // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 1 is const-qualified
-// BUG(b/27584482): void F6(const int *);  should be pro

Re: [PATCH] D15031: CFG: Add CFGElement for automatic variables that leave the scope

2016-04-21 Thread Matthias Gehre via cfe-commits
mgehre added a comment.

Ping


http://reviews.llvm.org/D15031



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


Re: [PATCH] D18914: [clang-tidy] new readability-redundant-inline

2016-05-10 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 56800.
mgehre added a comment.

Update for review comment:

- Return Optional when looking for 'inline'
- Add test that hides 'inline' in a macro


http://reviews.llvm.org/D18914

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tidy/readability/RedundantInlineCheck.cpp
  clang-tidy/readability/RedundantInlineCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-redundant-inline.rst
  test/clang-tidy/readability-redundant-inline.cpp

Index: test/clang-tidy/readability-redundant-inline.cpp
===
--- /dev/null
+++ test/clang-tidy/readability-redundant-inline.cpp
@@ -0,0 +1,77 @@
+// RUN: %check_clang_tidy %s readability-redundant-inline %t
+
+struct S {
+  inline int f1() {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because method body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  int f1()
+return 0;
+  }
+  inline int f2(); // OK
+
+  inline constexpr int f3() {
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'inline' is redundant because 'constexpr' implies 'inline' [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  constexpr int f3()
+return 0;
+  }
+  static inline constexpr int f4() {
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'inline' is redundant because 'constexpr' implies 'inline'
+// CHECK-FIXES: {{^}}  static constexpr int f4()
+return 0;
+  }
+
+  static inline int f5();
+
+  static inline int f6() {
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  static int f6()
+return 0;
+  }
+
+  inline friend int f7() {
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'inline' is redundant because function body is defined inside class [readability-redundant-inline]
+// CHECK-FIXES: {{^}}  friend int f7()
+  return 0;
+  }
+
+  inline friend int f8(); // OK
+
+  template struct T{};
+  struct T inline f9() { return {}; }
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  struct T f9() { return {}; }
+
+#define INLINE inline
+  INLINE void f10() {
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'inline' is redundant because method body is defined inside class
+  }
+};
+
+class S2 {
+  inline int f1() {
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: 'inline' is redundant because method body is defined inside class
+// CHECK-FIXES: {{^}}  int f1()
+return 0;
+  }
+};
+
+inline int S::f2() { // OK
+  return 0;
+}
+
+inline int S::f5() { // OK
+  return 0;
+}
+
+inline int f3() { // OK
+  return 0;
+}
+
+inline constexpr int f4() {
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 'inline' is redundant because 'constexpr' implies 'inline'
+// CHECK-FIXES: {{^}}constexpr int f4()
+  return 1;
+}
+
+constexpr int f5() { // OK
+  return 1;
+}
Index: docs/clang-tidy/checks/readability-redundant-inline.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/readability-redundant-inline.rst
@@ -0,0 +1,16 @@
+.. title:: clang-tidy - readability-redundant-inline
+
+readability-redundant-inline
+
+
+This check flags redundant ``inline`` specifiers.
+It flags ``inline`` on member functions defined inside a class definition like
+.. code-block:: c++
+
+  struct S {
+inline int f() {
+  return 0;
+}
+  };
+
+and ``inline`` specifiers on functions that are also declared ``constexpr``.
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -105,6 +105,7 @@
readability-inconsistent-declaration-parameter-name
readability-named-parameter
readability-redundant-control-flow
+   readability-redundant-inline
readability-redundant-smartptr-get
readability-redundant-string-cstr
readability-redundant-string-init
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -160,6 +160,12 @@
   Looks for procedures (functions returning no value) with ``return`` statements
   at the end of the function.  Such `return` statements are redundant.
 
+- New `readability-redundant-inline
+  `_ check
+
+  Looks for redundant ``inline`` specifiers which are implied by defining a body within a class definition
+  or by ``constexpr``.
+
 - New `readability-redundant-string-init
   `_ check
 
Index: clang-tidy/readability/RedundantInlineCheck.h
=

[PATCH] D13639: Add decayedType and hasDecayedType AST matchers

2015-10-11 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added a reviewer: klimek.
mgehre added a subscriber: cfe-commits.
Herald added a subscriber: klimek.

Add decayedType and hasDecayedType AST matchers

http://reviews.llvm.org/D13639

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  lib/ASTMatchers/Dynamic/Registry.cpp

Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -152,6 +152,7 @@
   REGISTER_MATCHER(cxxThrowExpr);
   REGISTER_MATCHER(cxxTryStmt);
   REGISTER_MATCHER(cxxUnresolvedConstructExpr);
+  REGISTER_MATCHER(decayedType);
   REGISTER_MATCHER(decl);
   REGISTER_MATCHER(declaratorDecl);
   REGISTER_MATCHER(declCountIs);
@@ -199,6 +200,7 @@
   REGISTER_MATCHER(hasCaseConstant);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
+  REGISTER_MATCHER(hasDecayedType);
   REGISTER_MATCHER(hasDeclaration);
   REGISTER_MATCHER(hasDeclContext);
   REGISTER_MATCHER(hasDeducedType);
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -4123,6 +4123,24 @@
 /// \endcode
 AST_TYPE_MATCHER(InjectedClassNameType, injectedClassNameType);
 
+/// \brief Matches decayed type
+/// Example matches i[] in declaration of f.
+/// (matcher = 
valueDecl(hasType(decayedType(hasDecayedType(pointerType())
+/// Example matches i[1].
+/// (matcher = expr(hasType(decayedType(hasDecayedType(pointerType())
+/// \code
+///   void f(int i[]) {
+/// i[1] = 0;
+///   }
+/// \endcode
+AST_TYPE_MATCHER(DecayedType, decayedType);
+
+/// \brief Matches the decayed type, whos decayed type matches \c InnerMatcher
+AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher,
+  InnerType) {
+  return InnerType.matches(Node.getDecayedType(), Finder, Builder);
+}
+
 /// \brief Matches declarations whose declaration context, interpreted as a
 /// Decl, matches \c InnerMatcher.
 ///


Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -152,6 +152,7 @@
   REGISTER_MATCHER(cxxThrowExpr);
   REGISTER_MATCHER(cxxTryStmt);
   REGISTER_MATCHER(cxxUnresolvedConstructExpr);
+  REGISTER_MATCHER(decayedType);
   REGISTER_MATCHER(decl);
   REGISTER_MATCHER(declaratorDecl);
   REGISTER_MATCHER(declCountIs);
@@ -199,6 +200,7 @@
   REGISTER_MATCHER(hasCaseConstant);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
+  REGISTER_MATCHER(hasDecayedType);
   REGISTER_MATCHER(hasDeclaration);
   REGISTER_MATCHER(hasDeclContext);
   REGISTER_MATCHER(hasDeducedType);
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -4123,6 +4123,24 @@
 /// \endcode
 AST_TYPE_MATCHER(InjectedClassNameType, injectedClassNameType);
 
+/// \brief Matches decayed type
+/// Example matches i[] in declaration of f.
+/// (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType())
+/// Example matches i[1].
+/// (matcher = expr(hasType(decayedType(hasDecayedType(pointerType())
+/// \code
+///   void f(int i[]) {
+/// i[1] = 0;
+///   }
+/// \endcode
+AST_TYPE_MATCHER(DecayedType, decayedType);
+
+/// \brief Matches the decayed type, whos decayed type matches \c InnerMatcher
+AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher,
+  InnerType) {
+  return InnerType.matches(Node.getDecayedType(), Finder, Builder);
+}
+
 /// \brief Matches declarations whose declaration context, interpreted as a
 /// Decl, matches \c InnerMatcher.
 ///
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D13639: Add decayedType and hasDecayedType AST matchers

2015-10-11 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 37066.
mgehre added a comment.

Add test


http://reviews.llvm.org/D13639

Files:
  include/clang/ASTMatchers/ASTMatchers.h
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/ASTMatchers/ASTMatchersTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -4109,6 +4109,11 @@
   EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger(;
 }
 
+TEST(TypeMatching, DecayedType) {
+  EXPECT_TRUE(matches("void f(int i[]);", 
valueDecl(hasType(decayedType(hasDecayedType(pointerType()));
+  EXPECT_TRUE(notMatches("int i[7];", decayedType()));
+}
+
 TEST(TypeMatching, MatchesComplexTypes) {
   EXPECT_TRUE(matches("_Complex float f;", complexType()));
   EXPECT_TRUE(matches(
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -152,6 +152,7 @@
   REGISTER_MATCHER(cxxThrowExpr);
   REGISTER_MATCHER(cxxTryStmt);
   REGISTER_MATCHER(cxxUnresolvedConstructExpr);
+  REGISTER_MATCHER(decayedType);
   REGISTER_MATCHER(decl);
   REGISTER_MATCHER(declaratorDecl);
   REGISTER_MATCHER(declCountIs);
@@ -199,6 +200,7 @@
   REGISTER_MATCHER(hasCaseConstant);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
+  REGISTER_MATCHER(hasDecayedType);
   REGISTER_MATCHER(hasDeclaration);
   REGISTER_MATCHER(hasDeclContext);
   REGISTER_MATCHER(hasDeducedType);
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -4123,6 +4123,24 @@
 /// \endcode
 AST_TYPE_MATCHER(InjectedClassNameType, injectedClassNameType);
 
+/// \brief Matches decayed type
+/// Example matches i[] in declaration of f.
+/// (matcher = 
valueDecl(hasType(decayedType(hasDecayedType(pointerType())
+/// Example matches i[1].
+/// (matcher = expr(hasType(decayedType(hasDecayedType(pointerType())
+/// \code
+///   void f(int i[]) {
+/// i[1] = 0;
+///   }
+/// \endcode
+AST_TYPE_MATCHER(DecayedType, decayedType);
+
+/// \brief Matches the decayed type, whos decayed type matches \c InnerMatcher
+AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher,
+  InnerType) {
+  return InnerType.matches(Node.getDecayedType(), Finder, Builder);
+}
+
 /// \brief Matches declarations whose declaration context, interpreted as a
 /// Decl, matches \c InnerMatcher.
 ///


Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -4109,6 +4109,11 @@
   EXPECT_TRUE(matches("const int a = 0;", qualType(isInteger(;
 }
 
+TEST(TypeMatching, DecayedType) {
+  EXPECT_TRUE(matches("void f(int i[]);", valueDecl(hasType(decayedType(hasDecayedType(pointerType()));
+  EXPECT_TRUE(notMatches("int i[7];", decayedType()));
+}
+
 TEST(TypeMatching, MatchesComplexTypes) {
   EXPECT_TRUE(matches("_Complex float f;", complexType()));
   EXPECT_TRUE(matches(
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -152,6 +152,7 @@
   REGISTER_MATCHER(cxxThrowExpr);
   REGISTER_MATCHER(cxxTryStmt);
   REGISTER_MATCHER(cxxUnresolvedConstructExpr);
+  REGISTER_MATCHER(decayedType);
   REGISTER_MATCHER(decl);
   REGISTER_MATCHER(declaratorDecl);
   REGISTER_MATCHER(declCountIs);
@@ -199,6 +200,7 @@
   REGISTER_MATCHER(hasCaseConstant);
   REGISTER_MATCHER(hasCondition);
   REGISTER_MATCHER(hasConditionVariableStatement);
+  REGISTER_MATCHER(hasDecayedType);
   REGISTER_MATCHER(hasDeclaration);
   REGISTER_MATCHER(hasDeclContext);
   REGISTER_MATCHER(hasDeducedType);
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -4123,6 +4123,24 @@
 /// \endcode
 AST_TYPE_MATCHER(InjectedClassNameType, injectedClassNameType);
 
+/// \brief Matches decayed type
+/// Example matches i[] in declaration of f.
+/// (matcher = valueDecl(hasType(decayedType(hasDecayedType(pointerType())
+/// Example matches i[1].
+/// (matcher = expr(hasType(decayedType(hasDecayedType(pointerType())
+/// \code
+///   void f(int i[]) {
+/// i[1] = 0;
+///   }
+/// \endcode
+AST_TYPE_MATCHER(DecayedType, decayedType);
+
+/// \brief Matches the decayed type, whos decayed type matches \c InnerMatcher
+AST_MATCHER_P(DecayedType, hasDecayedType, internal::Matcher,
+  InnerType) {
+  return InnerType.matche

[clang-tools-extra] r250002 - Test commit

2015-10-11 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Sun Oct 11 17:55:29 2015
New Revision: 250002

URL: http://llvm.org/viewvc/llvm-project?rev=250002&view=rev
Log:
Test commit

Modified:

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp?rev=250002&r1=250001&r2=250002&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
 Sun Oct 11 17:55:29 2015
@@ -17,6 +17,7 @@ namespace clang {
 namespace tidy {
 namespace cppcoreguidelines {
 
+/// A module containing checks of the C++ Core Guidelines
 class CppCoreGuidelinesModule : public ClangTidyModule {
 public:
   void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override {


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


[PATCH] D13640: [clang-tidy] Add new check cppcoreguidelines-pro-bounds-array-to-pointer-decay

2015-10-11 Thread Matthias Gehre via cfe-commits
mgehre created this revision.
mgehre added reviewers: alexfh, sbenza, bkramer, aaron.ballman.
mgehre added a subscriber: cfe-commits.

This check flags all array to pointer decays.

Pointers should not be used as arrays. array_view is a bounds-checked,
safe alternative to using pointers to access arrays.

This rule is part of the "Bounds safety" profile of the C++ Core
Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds3-no-array-to-pointer-decay

http://reviews.llvm.org/D13640

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
  clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-array-to-pointer-decay.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
@@ -0,0 +1,26 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-bounds-array-to-pointer-decay %t
+
+void pointerfun(int* p);
+void arrayfun(int p[]);
+
+void f()
+{
+  int a[5];
+  pointerfun(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not (implicitly) convert an array to a pointer [cppcoreguidelines-pro-bounds-array-to-pointer-decay]
+  pointerfun((int*)a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: do not (implicitly) convert an array to a pointer
+  arrayfun(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not (implicitly) convert an array to a pointer
+
+  int i = a[0]; // OK
+  pointerfun(&a[0]); // OK
+
+  for(auto e : a ) // OK, iteration internally decays array to pointer
+;
+}
+
+const char* g()
+{
+return "clang"; // OK, decay string literal to pointer
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -4,6 +4,7 @@
 .. toctree::
cert-setlongjmp
cert-variadic-function-def
+   cppcoreguidelines-pro-bounds-array-to-pointer-decay
cppcoreguidelines-pro-type-const-cast
cppcoreguidelines-pro-type-reinterpret-cast
google-build-explicit-make-pair
Index: docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-array-to-pointer-decay.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/cppcoreguidelines-pro-bounds-array-to-pointer-decay.rst
@@ -0,0 +1,9 @@
+cppcoreguidelines-pro-bounds-array-to-pointer-decay
+===
+
+This check flags all array to pointer decays.
+
+Pointers should not be used as arrays. array_view is a bounds-checked, safe alternative to using pointers to access arrays.
+
+This rule is part of the "Bounds safety" profile of the C++ Core Guidelines, see
+https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-bounds3-no-array-to-pointer-decay
Index: clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h
@@ -0,0 +1,34 @@
+//===--- ProBoundsArrayToPointerDecayCheck.h - clang-tidy*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_ARRAY_TO_POINTER_DECAY_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_ARRAY_TO_POINTER_DECAY_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+
+/// This check flags all array to pointer decays
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/cppcoreguidelines-pro-bounds-array-to-pointer-decay.html
+class ProBoundsArrayToPointerDecayCheck : public ClangTidyCheck {
+public:
+  ProBoundsArrayToPointerDecayCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_CPPCOREGUIDELINES_PRO_BOUNDS_ARRAY_TO_POINTER_DECAY_H
+
Index: clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp
===
--- /dev/null
+++ clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDec

Re: [PATCH] D13368: [clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

2015-10-12 Thread Matthias Gehre via cfe-commits
mgehre updated this revision to Diff 37155.
mgehre marked an inline comment as done.
mgehre added a comment.

Add test for static_cast with const


http://reviews.llvm.org/D13368

Files:
  clang-tidy/cppcoreguidelines/CMakeLists.txt
  clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
  clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h
  docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp

Index: test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
===
--- /dev/null
+++ test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
@@ -0,0 +1,118 @@
+// RUN: %python %S/check_clang_tidy.py %s cppcoreguidelines-pro-type-static-cast-downcast %t
+
+class Base {
+};
+
+class Derived : public Base {
+};
+
+class Base2 {
+};
+
+class MultiDerived : public Base, public Base2 {
+};
+
+class PolymorphicBase {
+public:
+  virtual ~PolymorphicBase();
+};
+
+class PolymorphicDerived : public PolymorphicBase {
+};
+
+class PolymorphicMultiDerived : public Base, public PolymorphicBase {
+};
+
+void pointers() {
+
+  auto P0 = static_cast(new Base());
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  const Base* B0;
+  auto PC0 = static_cast(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  auto P1 = static_cast(new Derived()); // OK, upcast to a public base
+  auto P2 = static_cast(new MultiDerived()); // OK, upcast to a public base
+  auto P3 = static_cast(new MultiDerived()); // OK, upcast to a public base
+}
+
+void pointers_polymorphic() {
+
+  auto PP0 = static_cast(new PolymorphicBase());
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto PP0 = dynamic_cast(new PolymorphicBase());
+
+  const PolymorphicBase* B0;
+  auto PPC0 = static_cast(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto PPC0 = dynamic_cast(B0);
+
+
+  auto B1 = static_cast(new PolymorphicDerived()); // OK, upcast to a public base
+  auto B2 = static_cast(new PolymorphicMultiDerived()); // OK, upcast to a public base
+  auto B3 = static_cast(new PolymorphicMultiDerived()); // OK, upcast to a public base
+}
+
+void arrays() {
+  Base ArrayOfBase[10];
+  auto A0 = static_cast(ArrayOfBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+}
+
+void arrays_polymorphic() {
+  PolymorphicBase ArrayOfPolymorphicBase[10];
+  auto AP0 = static_cast(ArrayOfPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto AP0 = dynamic_cast(ArrayOfPolymorphicBase);
+}
+
+void references() {
+  Base B0;
+  auto R0 = static_cast(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+  Base& RefToBase = B0;
+  auto R1 = static_cast(RefToBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  const Base& ConstRefToBase = B0;
+  auto RC1 = static_cast(ConstRefToBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+
+  Derived RD1;
+  auto R2 = static_cast(RD1); // OK, upcast to a public base
+}
+
+void references_polymorphic() {
+  PolymorphicBase B0;
+  auto RP0 = static_cast(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto RP0 = dynamic_cast(B0);
+
+  PolymorphicBase& RefToPolymorphicBase = B0;
+  auto RP1 = static_cast(RefToPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto RP1 = dynamic_cast(RefToPolymorphicBase);
+
+  const PolymorphicBase& ConstRefToPolymorphicBase = B0;
+  auto RPC2 = static_cast(ConstRefToPolymorphicBase);
+  //

[clang-tools-extra] r250098 - [clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

2015-10-12 Thread Matthias Gehre via cfe-commits
Author: mgehre
Date: Mon Oct 12 15:46:53 2015
New Revision: 250098

URL: http://llvm.org/viewvc/llvm-project?rev=250098&view=rev
Log:
[clang-tidy] add check cppcoreguidelines-pro-type-static-cast-downcast

Summary:
This check flags all usages of static_cast, where a base class is casted
to a derived class.
In those cases, a fixit is provided to convert the cast to a
dynamic_cast.

Use of these casts can violate type safety and cause the program to
access a variable that is actually of type X to be accessed as if it
were of an unrelated type Z.

This rule is part of the "Type safety" profile of the C++ Core
Guidelines, see
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#-type2-dont-use-static_cast-downcasts-use-dynamic_cast-instead

Depends on D13313

Reviewers: alexfh, sbenza, bkramer, aaron.ballman

Subscribers: cfe-commits

Differential Revision: http://reviews.llvm.org/D13368

Added:

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h

clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-pro-type-static-cast-downcast.rst

clang-tools-extra/trunk/test/clang-tidy/cppcoreguidelines-pro-type-static-cast-downcast.cpp
Modified:
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt?rev=250098&r1=250097&r2=250098&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt 
(original)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt Mon Oct 
12 15:46:53 2015
@@ -4,6 +4,7 @@ add_clang_library(clangTidyCppCoreGuidel
   CppCoreGuidelinesTidyModule.cpp
   ProTypeConstCastCheck.cpp
   ProTypeReinterpretCastCheck.cpp
+  ProTypeStaticCastDowncastCheck.cpp
 
   LINK_LIBS
   clangAST

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp?rev=250098&r1=250097&r2=250098&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
 Mon Oct 12 15:46:53 2015
@@ -12,6 +12,7 @@
 #include "../ClangTidyModuleRegistry.h"
 #include "ProTypeConstCastCheck.h"
 #include "ProTypeReinterpretCastCheck.h"
+#include "ProTypeStaticCastDowncastCheck.h"
 
 namespace clang {
 namespace tidy {
@@ -25,6 +26,8 @@ public:
 "cppcoreguidelines-pro-type-const-cast");
 CheckFactories.registerCheck(
 "cppcoreguidelines-pro-type-reinterpret-cast");
+CheckFactories.registerCheck(
+"cppcoreguidelines-pro-type-static-cast-downcast");
   }
 };
 

Added: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp?rev=250098&view=auto
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
 (added)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp
 Mon Oct 12 15:46:53 2015
@@ -0,0 +1,52 @@
+//===--- ProTypeStaticCastDowncastCheck.cpp - 
clang-tidy---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "ProTypeStaticCastDowncastCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+
+void ProTypeStaticCastDowncastCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+return;
+
+  Finder->addMatcher(
+  cxxStaticCastExpr(unless(isInTemplateInstantiation())).bind("cast"),
+  this);
+}
+
+void ProTypeStaticCastDowncastCheck::check(const MatchFinder::MatchResult 
&Result) {
+  const auto *MatchedCast = Result.Nodes.getNodeAs("cast");
+  if (MatchedCast->getCastKind() != CK_BaseToDerived)
+return;
+
+  QualType SourceType = MatchedCast->getSubExpr()->getType();
+  const auto *SourceDecl = Sour

  1   2   3   >