[PATCH] D41880: Adding nocf_check attribute for cf-protection fine tuning

2018-02-27 Thread Oren Ben Simhon via Phabricator via cfe-commits
oren_ben_simhon updated this revision to Diff 136235.
oren_ben_simhon added a comment.

Implemented commented posted by Aaron (Thanks)


Repository:
  rL LLVM

https://reviews.llvm.org/D41880

Files:
  include/clang/AST/Type.h
  include/clang/Basic/Attr.td
  include/clang/Basic/AttrDocs.td
  include/clang/Basic/DiagnosticSemaKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/CodeGen/CGFunctionInfo.h
  include/clang/Sema/Sema.h
  lib/AST/ASTContext.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/CodeGen/CGCall.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/CodeGen/attributes.c
  test/CodeGen/cetintrin.c
  test/CodeGen/x86-cf-protection.c
  test/Misc/pragma-attribute-supported-attributes-list.test
  test/Sema/attr-nocf_check.c
  test/Sema/attr-nocf_check.cpp
  test/Sema/nocf_check_attr_not_allowed.c

Index: test/Sema/nocf_check_attr_not_allowed.c
===
--- /dev/null
+++ test/Sema/nocf_check_attr_not_allowed.c
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -triple powerpc-unknown-linux-gnu -fsyntax-only -verify -fcf-protection=branch %s
+// RUN: %clang_cc1 -triple arm-unknown-linux-gnu -fsyntax-only -verify -fcf-protection=branch %s
+// RUN: %clang_cc1 -triple arm-unknown-linux-gnu -fsyntax-only -verify %s
+
+void __attribute__((nocf_check)) foo(); // expected-warning-re((unknown attribute 'nocf_check' ignored)|('nocf_check' attribute ignored; use -fcf-protection to enable the attribute))
Index: test/Sema/attr-nocf_check.cpp
===
--- /dev/null
+++ test/Sema/attr-nocf_check.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple=i386-unknown-unknown -verify -fcf-protection=branch -target-feature +ibt -std=c++11 -fsyntax-only %s
+
+// Function pointer definition.
+[[gnu::nocf_check]] typedef void (*FuncPointerWithNoCfCheck)(void); // no-warning
+typedef void (*FuncPointer)(void);
+
+// Dont allow function declaration and definition mismatch.
+[[gnu::nocf_check]] void testNoCfCheck();   // expected-note {{previous declaration is here}}
+void testNoCfCheck(){}; //  expected-error {{conflicting types for 'testNoCfCheck'}}
+
+// No variable or parameter declaration
+int [[gnu::nocf_check]] i;  // expected-error {{'nocf_check' attribute cannot be applied to types}}
+void testNoCfCheckImpl(double i [[gnu::nocf_check]]) {} // expected-warning {{'nocf_check' attribute only applies to functions and function pointers}}
+
+// Allow attributed function pointers as well as casting between attributed
+// and non-attributed function pointers.
+void testNoCfCheckMismatch(FuncPointer f) {
+  FuncPointerWithNoCfCheck fNoCfCheck = f; // expected-error {{cannot initialize a variable of type}}
+  (*fNoCfCheck)(); // no-warning
+}
+
+// 'nocf_check' Attribute has no parameters.
+[[gnu::nocf_check(1)]] int testNoCfCheckParams(); // expected-error {{'nocf_check' attribute takes no arguments}}
Index: test/Sema/attr-nocf_check.c
===
--- /dev/null
+++ test/Sema/attr-nocf_check.c
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -triple=x86_64-unknown-unknown -verify -fcf-protection=branch -target-feature +ibt -fsyntax-only %s
+
+// Function pointer definition.
+typedef void (*FuncPointerWithNoCfCheck)(void) __attribute__((nocf_check)); // no-warning
+typedef void (*FuncPointer)(void);
+
+// Dont allow function declaration and definition mismatch.
+void __attribute__((nocf_check)) testNoCfCheck();   // expected-note {{previous declaration is here}}
+void testNoCfCheck(){}; //  expected-error {{conflicting types for 'testNoCfCheck'}}
+
+// No variable or parameter declaration
+__attribute__((nocf_check)) int i;  // expected-warning {{'nocf_check' attribute only applies to function}}
+void testNoCfCheckImpl(double __attribute__((nocf_check)) i) {} // expected-warning {{'nocf_check' attribute only applies to function}}
+
+// Allow attributed function pointers as well as casting between attributed
+// and non-attributed function pointers.
+void testNoCfCheckMismatch(FuncPointer f) {
+  FuncPointerWithNoCfCheck fNoCfCheck = f; // expected-warning {{incompatible function pointer types}}
+  (*fNoCfCheck)(); // no-warning
+}
+
+// 'nocf_check' Attribute has no parameters.
+int testNoCfCheckParams() __attribute__((nocf_check(1))); // expected-error {{'nocf_check' attribute takes no arguments}}
Index: test/Misc/pragma-attribute-supported-attributes-list.test
===
--- test/Misc/pragma-attribute-supported-attributes-list.test
+++ test/Misc/pragma-attribute-supported-attributes-list.test
@@ -2,7 +2,7 @@
 
 // The number of supported attributes should never go down!
 
-// CHECK: #pragma 

[PATCH] D39562: [CodeGen][ObjC] Fix an assertion failure caused by copy elision

2018-02-27 Thread Shoaib Meenai via Phabricator via cfe-commits
smeenai added a comment.

Any updates here? We were hitting a similar error internally, which this patch 
fixed.


https://reviews.llvm.org/D39562



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


[PATCH] D41228: [ObjC] Enable __strong pointers in structs under ARC

2018-02-27 Thread Akira Hatanaka via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326307: [ObjC] Allow declaring __strong pointer fields in 
structs in Objective-C (authored by ahatanak, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D41228?vs=135703&id=136232#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D41228

Files:
  cfe/trunk/docs/LanguageExtensions.rst
  cfe/trunk/include/clang/AST/Decl.h
  cfe/trunk/include/clang/AST/Type.h
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/lib/AST/ASTContext.cpp
  cfe/trunk/lib/AST/Decl.cpp
  cfe/trunk/lib/AST/Type.cpp
  cfe/trunk/lib/CodeGen/CGBlocks.cpp
  cfe/trunk/lib/CodeGen/CGCall.cpp
  cfe/trunk/lib/CodeGen/CGDecl.cpp
  cfe/trunk/lib/CodeGen/CGDeclCXX.cpp
  cfe/trunk/lib/CodeGen/CGExprAgg.cpp
  cfe/trunk/lib/CodeGen/CGNonTrivialStruct.cpp
  cfe/trunk/lib/CodeGen/CMakeLists.txt
  cfe/trunk/lib/CodeGen/CodeGenFunction.h
  cfe/trunk/lib/Lex/PPMacroExpansion.cpp
  cfe/trunk/lib/Sema/JumpDiagnostics.cpp
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/lib/Sema/SemaExpr.cpp
  cfe/trunk/test/ARCMT/checking.m
  cfe/trunk/test/CodeGenObjC/nontrivial-c-struct-exception.m
  cfe/trunk/test/CodeGenObjC/nontrivial-c-struct-func-name-collision.m
  cfe/trunk/test/CodeGenObjC/strong-in-c-struct.m
  cfe/trunk/test/Lexer/has_feature_objc_arc.m
  cfe/trunk/test/SemaObjC/arc-decls.m
  cfe/trunk/test/SemaObjC/arc-system-header.m
  cfe/trunk/test/SemaObjC/strong-in-c-struct.m

Index: cfe/trunk/test/ARCMT/checking.m
===
--- cfe/trunk/test/ARCMT/checking.m
+++ cfe/trunk/test/ARCMT/checking.m
@@ -116,7 +116,7 @@
 }
 
 struct S {
-  A* a; // expected-error {{ARC forbids Objective-C objects in struct}}
+  A* a;
 };
 
 @interface B
Index: cfe/trunk/test/SemaObjC/arc-system-header.m
===
--- cfe/trunk/test/SemaObjC/arc-system-header.m
+++ cfe/trunk/test/SemaObjC/arc-system-header.m
@@ -23,8 +23,7 @@
 }
 
 void test5(struct Test5 *p) {
-  p->field = 0; // expected-error {{'field' is unavailable in ARC}}
-// expected-note@arc-system-header.h:25 {{field has non-trivial ownership qualification}}
+  p->field = 0;
 }
 
 id test6() {
@@ -49,8 +48,7 @@
 
 extern void doSomething(Test9 arg);
 void test9() {
-Test9 foo2 = {0, 0}; // expected-error {{'field' is unavailable in ARC}}
- // expected-note@arc-system-header.h:56 {{field has non-trivial ownership qualification}}
+Test9 foo2 = {0, 0};
 doSomething(foo2);
 }
 #endif
Index: cfe/trunk/test/SemaObjC/arc-decls.m
===
--- cfe/trunk/test/SemaObjC/arc-decls.m
+++ cfe/trunk/test/SemaObjC/arc-decls.m
@@ -3,7 +3,7 @@
 // rdar://8843524
 
 struct A {
-id x; // expected-error {{ARC forbids Objective-C objects in struct}}
+id x;
 };
 
 union u {
@@ -13,7 +13,7 @@
 @interface I {
struct A a; 
struct B {
-id y[10][20]; // expected-error {{ARC forbids Objective-C objects in struct}}
+id y[10][20];
 id z;
} b;
 
@@ -23,7 +23,7 @@
 
 // rdar://10260525
 struct r10260525 {
-  id (^block) (); // expected-error {{ARC forbids blocks in struct}}
+  id (^block) ();
 };
 
 struct S { 
Index: cfe/trunk/test/SemaObjC/strong-in-c-struct.m
===
--- cfe/trunk/test/SemaObjC/strong-in-c-struct.m
+++ cfe/trunk/test/SemaObjC/strong-in-c-struct.m
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -fobjc-arc -fblocks  -fobjc-runtime=ios-11.0 -fsyntax-only -verify %s
+
+typedef struct {
+  id a;
+} Strong;
+
+void callee_variadic(const char *, ...);
+
+void test_variadic(void) {
+  Strong t;
+  callee_variadic("s", t); // expected-error {{cannot pass non-trivial C object of type 'Strong' by value to variadic function}}
+}
+
+void test_jump0(int cond) {
+  switch (cond) {
+  case 0:
+;
+Strong x; // expected-note {{jump bypasses initialization of variable of non-trivial C struct type}}
+break;
+  case 1: // expected-error {{cannot jump from switch statement to this case label}}
+x.a = 0;
+break;
+  }
+}
+
+void test_jump1(void) {
+  static void *ips[] = { &&L0 };
+L0:  // expected-note {{possible target of indirect goto}}
+  ;
+  Strong x; // expected-note {{jump exits scope of variable with non-trivial destructor}}
+  goto *ips; // expected-error {{cannot jump}}
+}
+
+typedef void (^BlockTy)(void);
+void func(BlockTy);
+void func2(Strong);
+
+void test_block_scope0(int cond) {
+  Strong x; // expected-note {{jump enters lifetime of block which captures a C struct that is non-trivial to destroy}}
+  switch (cond) {
+  case 0:
+func(^{ func2(x); });
+break;
+  default: // expected-error {{cannot jump from switch statement to this case label}}
+break;
+  }
+}
+
+void test_block_scope1(void) {
+  static void *ips[]

[PATCH] D43737: Improve -Winfinite-recursion

2018-02-27 Thread Robert Widmann via Phabricator via cfe-commits
CodaFi added a comment.

> Can you explain the new algorithm for checking recursive calls?

The idea is to de-clutter as much of the existing algorithm as possible.  The 
state dictionary is done away with now in favor of just not enqueueing 
successors of CFG blocks that have recursive calls.  Given an arbitrary CFG, 
the algorithm attempts DFS for a path from the entry node to the exit node - 
terminating search on any path dominated by a recursive call.

>   but it doesn't trigger the warning.

There's a condition around the reachability of the exit node hindering that 
that I didn't want to touch.  I believe you were around this code last, so can 
you remember why it was there?


https://reviews.llvm.org/D43737



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


[PATCH] D43737: Improve -Winfinite-recursion

2018-02-27 Thread Richard Trieu via Phabricator via cfe-commits
rtrieu added inline comments.



Comment at: lib/Sema/AnalysisBasedWarnings.cpp:255-257
   // If the exit block is unreachable, skip processing the function.
   if (cfg->getExit().pred_empty())
 return;

This is likely what is causing my previous code example to fail.


https://reviews.llvm.org/D43737



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


[PATCH] D43737: Improve -Winfinite-recursion

2018-02-27 Thread Richard Trieu via Phabricator via cfe-commits
rtrieu added a comment.

Can you explain the new algorithm for checking recursive calls?

From the test, this code looks like what you are testing for, but it doesn't 
trigger the warning.

  void f() {
while(true) {
  f();
}
  } 


https://reviews.llvm.org/D43737



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


[PATCH] D43322: Diagnose cases of "return x" that should be "return std::move(x)" for efficiency

2018-02-27 Thread Richard Trieu via Phabricator via cfe-commits
rtrieu added a comment.



> I have one very minor nit that I don't know how to fix:
> 
>   warn-return-std-move.cpp:220:12: warning: local variable 'd' will be copied
> despite being returned by name [-Wreturn-std-move]
>   return (d);  // e17
>  ^
>   warn-return-std-move.cpp:220:12: note: call 'std::move' explicitly to avoid 
> copying
>   return (d);  // e17
>  ^~~
>  std::move(d)
> 
> 
> The warning places a caret directly under the `(`, when I wish it would place 
> `^~~` under the entire expression, the way the fixit does.

You can add extra tildes to any diagnostic by passing a SourceRange to Diag() 
calls the same way you pass FixitHints.




Comment at: lib/Sema/SemaStmt.cpp:2937
 
+static void AttemptMoveInitialization(Sema& S,
+  const InitializedEntity &Entity,

I have a few concerns about this function.  The code isn't a straight move from 
the old location to this one, so it is hard to follow along the changes, 
especially the change to the complex if conditional.  The function should be 
commented, especially to behavior difference for setting IsFake.

It looks like when IsFake is set, then the result is discarded and not used, 
but it is still possible on success for AsRvalue to be copied to the heap.  
This is wasteful when it is never used again.

Another issue is the Value in the original code is used again towards the end 
of the function on line #3013.  In the old code, Value can be updated while in 
the new code, it does.

It may be better to split this change in two, the first adding this function 
and the CopyElisionSemanticsKind enum and the second adding the diagnostic 
itself.


Repository:
  rC Clang

https://reviews.llvm.org/D43322



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


[PATCH] D41517: mmintrin.h documentation fixes and updates

2018-02-27 Thread Douglas Yung via Phabricator via cfe-commits
dyung marked an inline comment as done.
dyung added inline comments.



Comment at: lib/Headers/mmintrin.h:55
 ///
-/// This intrinsic corresponds to the  VMOVD / MOVD  instruction.
+/// This intrinsic corresponds to the  MOVD  instruction.
 ///

efriedma wrote:
> RKSimon wrote:
> > efriedma wrote:
> > > craig.topper wrote:
> > > > kromanova wrote:
> > > > > I tried clang on Linux, x86_64, and if -mavx option is passed, we 
> > > > > generate VMOVD, if this option is omitted, we generate MOVD.
> > > > > I think I understand the rational behind this change (namely, to keep 
> > > > > MOVD, but remove VMOVD),
> > > > > since this intrinsic should use MMX registers and shouldn't have 
> > > > > corresponding AVX instruction(s).
> > > > > 
> > > > > However, that's what we generate at the moment when -mavx is passed 
> > > > > (I suspect because our MMX support is limited)
> > > > > vmovd   %edi, %xmm0
> > > > > 
> > > > > Since we are writing the documentation for clang compiler, we should 
> > > > > document what clang compiler is doing, not what is should be doing.
> > > > > Craig, what do you think? Should we revert back to VMOVD/MOVD?
> > > > > 
> > > > We can change it back to VMOVD/MOVD
> > > The reference to vmovd seems confusing.  Yes, LLVM compiles 
> > > `_mm_movpi64_epi64(_mm_cvtsi32_si64(i))` to vmovd, but that doesn't mean 
> > > either of those intrinsics "corresponds" to vmovd; that's just the 
> > > optimizer combining two operations into one.
> > Should all these _mm_cvt* intrinsics be replaced with a 'this is a utility 
> > function' style comment like the _mm_set1* intrinsics?
> In general, I think "corresponds to" should mean "if the inputs are produced 
> by an inline asm, and the output is used by an inline asm, and the lowering 
> will produce a single instruction, what instruction will we generate?".  
> That's unambiguous, and will usually give a useful hint to the user.  In this 
> case, on trunk, the answer is consistently "movd".
> 
> Otherwise, it's not clear what it means for an intrinsic to correspond to 
> anything; optimizations exist which can modify the instructions we choose for 
> almost any intrinsic.
Thanks for the feedback. I wrote a few small examples and noted that the 
instructions generated by the compiler were the non-avx form by default for 
this and the next three _mm_cvt* intrinsics as you indicated, so I have updated 
the documentation to list the non-avx instruction. Additionally, in some 
discussions, it was pointed out that these are MMX intrinsics, so the AVX 
instructions would not have been generated.


https://reviews.llvm.org/D41517



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


[PATCH] D41517: mmintrin.h documentation fixes and updates

2018-02-27 Thread Douglas Yung via Phabricator via cfe-commits
dyung updated this revision to Diff 136221.
dyung added a comment.

Updated documentation for instruction generated for _mm_cvtsi32_si64, 
_mm_cvtsi64_si32, _mm_cvtsi64_m64 and _mm_cvtm64_si64 based on feedback.


https://reviews.llvm.org/D41517

Files:
  lib/Headers/mmintrin.h


Index: lib/Headers/mmintrin.h
===
--- lib/Headers/mmintrin.h
+++ lib/Headers/mmintrin.h
@@ -52,7 +52,7 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VMOVD / MOVD  instruction.
+/// This intrinsic corresponds to the  MOVD  instruction.
 ///
 /// \param __i
 ///A 32-bit integer value.
@@ -69,7 +69,7 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VMOVD / MOVD  instruction.
+/// This intrinsic corresponds to the  MOVD  instruction.
 ///
 /// \param __m
 ///A 64-bit integer vector.
@@ -85,7 +85,7 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VMOVQ / MOVD  instruction.
+/// This intrinsic corresponds to the  MOVQ  instruction.
 ///
 /// \param __i
 ///A 64-bit signed integer.
@@ -101,7 +101,7 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VMOVQ / MOVD  instruction.
+/// This intrinsic corresponds to the  MOVQ  instruction.
 ///
 /// \param __m
 ///A 64-bit integer vector.
@@ -1289,7 +1289,8 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VXORPS / XORPS  instruction.
+/// This intrinsic is a utility function and does not correspond to a specific
+///instruction.
 ///
 /// \returns An initialized 64-bit integer vector with all elements set to 
zero.
 static __inline__ __m64 __DEFAULT_FN_ATTRS
@@ -1381,7 +1382,8 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VPSHUFD / PSHUFD  instruction.
+/// This intrinsic is a utility function and does not correspond to a specific
+///instruction.
 ///
 /// \param __i
 ///A 32-bit integer value used to initialize each vector element of the
@@ -1399,7 +1401,8 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VPSHUFLW / PSHUFLW  instruction.
+/// This intrinsic is a utility function and does not correspond to a specific
+///instruction.
 ///
 /// \param __w
 ///A 16-bit integer value used to initialize each vector element of the
@@ -1416,8 +1419,8 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VPUNPCKLBW + VPSHUFLW / PUNPCKLBW +
-///PSHUFLW  instruction.
+/// This intrinsic is a utility function and does not correspond to a specific
+///instruction.
 ///
 /// \param __b
 ///An 8-bit integer value used to initialize each vector element of the


Index: lib/Headers/mmintrin.h
===
--- lib/Headers/mmintrin.h
+++ lib/Headers/mmintrin.h
@@ -52,7 +52,7 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VMOVD / MOVD  instruction.
+/// This intrinsic corresponds to the  MOVD  instruction.
 ///
 /// \param __i
 ///A 32-bit integer value.
@@ -69,7 +69,7 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VMOVD / MOVD  instruction.
+/// This intrinsic corresponds to the  MOVD  instruction.
 ///
 /// \param __m
 ///A 64-bit integer vector.
@@ -85,7 +85,7 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VMOVQ / MOVD  instruction.
+/// This intrinsic corresponds to the  MOVQ  instruction.
 ///
 /// \param __i
 ///A 64-bit signed integer.
@@ -101,7 +101,7 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VMOVQ / MOVD  instruction.
+/// This intrinsic corresponds to the  MOVQ  instruction.
 ///
 /// \param __m
 ///A 64-bit integer vector.
@@ -1289,7 +1289,8 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VXORPS / XORPS  instruction.
+/// This intrinsic is a utility function and does not correspond to a specific
+///instruction.
 ///
 /// \returns An initialized 64-bit integer vector with all elements set to zero.
 static __inline__ __m64 __DEFAULT_FN_ATTRS
@@ -1381,7 +1382,8 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VPSHUFD / PSHUFD  instruction.
+/// This intrinsic is a utility function and does not correspond to a specific
+///instruction.
 ///
 /// \param __i
 ///A 32-bit integer value used to initialize each vector element of the
@@ -1399,7 +1401,8 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VPSHUFLW / PSHUFLW  instruction.
+/// This intrinsic is a utility function and does not correspond to a specific
+///instruction.
 ///
 /// \param __w
 ///A 16-bit integer value used to initialize each vector element of the
@@ -1416,8 +1419,8 @@
 ///
 /// \headerfile 
 ///
-/// This intrinsic corresponds to the  VPUNPCKLBW + VPSHUFLW / PUNPCKLBW +
-///PSHUFLW  instruction.
+/// This intrinsic is a utility function and does not correspond to a specific
+///instruction.
 //

r326298 - Update cxx_status to mark "SVN" items as "Clang 6" instead.

2018-02-27 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Tue Feb 27 19:02:07 2018
New Revision: 326298

URL: http://llvm.org/viewvc/llvm-project?rev=326298&view=rev
Log:
Update cxx_status to mark "SVN" items as "Clang 6" instead.

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

Modified: cfe/trunk/www/cxx_status.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_status.html?rev=326298&r1=326297&r2=326298&view=diff
==
--- cfe/trunk/www/cxx_status.html (original)
+++ cfe/trunk/www/cxx_status.html Tue Feb 27 19:02:07 2018
@@ -799,22 +799,22 @@ as the draft C++2a standard evolves.
 
   Default member initializers for bit-fields
   http://wg21.link/p0683r1";>P0683R1
-  SVN
+  Clang 6
 
 
   const&-qualified pointers to members
   http://wg21.link/p0704r1";>P0704R1
-  SVN
+  Clang 6
 
 
   Allow lambda-capture [=, this]
   http://wg21.link/p0409r2";>P0409R2
-  SVN
+  Clang 6
 
 
   __VA_OPT__ for preprocessor comma elision
   http://wg21.link/p0306r4";>P0306R4
-  SVN
+  Clang 6
 
 
   Designated initializers
@@ -829,7 +829,7 @@ as the draft C++2a standard evolves.
 
   Initializer list constructors in class template argument 
deduction
   http://wg21.link/p0702r1";>P0702R1
-  SVN (13)
+  Clang 6 (13)
 
 
   Concepts

Modified: cfe/trunk/www/make_cxx_dr_status
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/www/make_cxx_dr_status?rev=326298&r1=326297&r2=326298&view=diff
==
--- cfe/trunk/www/make_cxx_dr_status (original)
+++ cfe/trunk/www/make_cxx_dr_status Tue Feb 27 19:02:07 2018
@@ -108,9 +108,12 @@ def availability(issue):
   if status == 'unknown':
 avail = 'Unknown'
 avail_style = ' class="none"'
-  elif status == '6':
+  elif status == '7':
 avail = 'SVN'
 avail_style = ' class="svn"'
+  elif status == '6':
+avail = 'Clang 6'
+avail_style = ' class="svn"'
   elif re.match('^[0-9]+\.?[0-9]*', status):
 avail = 'Clang %s' % status
 avail_style = ' class="full"'


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


r326299 - Fix a couple of cases where we would fail to correctly parse deduced class template specialization types.

2018-02-27 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Tue Feb 27 19:02:23 2018
New Revision: 326299

URL: http://llvm.org/viewvc/llvm-project?rev=326299&view=rev
Log:
Fix a couple of cases where we would fail to correctly parse deduced class 
template specialization types.

Specifically, we would not properly parse these types within template arguments
(for non-type template parameters), and in tentative parses. Fixing both of
these essentially requires that we parse deduced template specialization types
as types in all contexts, even in template argument lists -- in particular,
tentative parsing may look ahead and annotate a deduced template specialization
type before we figure out that we're actually supposed to treat the tokens as a
template-name. We deal with this by simply permitting deduced template
specialization types when parsing template arguments, and converting them to
template template arguments.

Modified:
cfe/trunk/include/clang/Sema/DeclSpec.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/TemplateName.cpp
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseTemplate.cpp
cfe/trunk/lib/Parse/ParseTentative.cpp
cfe/trunk/lib/Parse/Parser.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaType.cpp
cfe/trunk/test/CXX/temp/temp.deduct.guide/p3.cpp
cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp

Modified: cfe/trunk/include/clang/Sema/DeclSpec.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=326299&r1=326298&r2=326299&view=diff
==
--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)
+++ cfe/trunk/include/clang/Sema/DeclSpec.h Tue Feb 27 19:02:23 2018
@@ -326,6 +326,7 @@ public:
 PQ_TypeSpecifier = 2,
 PQ_TypeQualifier = 4,
 PQ_FunctionSpecifier = 8
+// FIXME: Attributes should be included here.
   };
 
 private:
@@ -1732,7 +1733,8 @@ enum class DeclaratorContext {
 ConversionIdContext, // C++ conversion-type-id.
 TrailingReturnContext, // C++11 trailing-type-specifier.
 TrailingReturnVarContext, // C++11 trailing-type-specifier for variable.
-TemplateTypeArgContext, // Template type argument.
+TemplateArgContext,  // Any template argument (in template argument list).
+TemplateTypeArgContext, // Template type argument (in default argument).
 AliasDeclContext,// C++11 alias-declaration.
 AliasTemplateContext // C++11 alias-declaration template.
 };
@@ -1949,6 +1951,7 @@ public:
 case DeclaratorContext::BlockLiteralContext:
 case DeclaratorContext::LambdaExprContext:
 case DeclaratorContext::ConversionIdContext:
+case DeclaratorContext::TemplateArgContext:
 case DeclaratorContext::TemplateTypeArgContext:
 case DeclaratorContext::TrailingReturnContext:
 case DeclaratorContext::TrailingReturnVarContext:
@@ -1986,6 +1989,7 @@ public:
 case DeclaratorContext::BlockLiteralContext:
 case DeclaratorContext::LambdaExprContext:
 case DeclaratorContext::ConversionIdContext:
+case DeclaratorContext::TemplateArgContext:
 case DeclaratorContext::TemplateTypeArgContext:
 case DeclaratorContext::TrailingReturnContext:
 case DeclaratorContext::TrailingReturnVarContext:
@@ -2027,6 +2031,7 @@ public:
 case DeclaratorContext::BlockLiteralContext:
 case DeclaratorContext::LambdaExprContext:
 case DeclaratorContext::ConversionIdContext:
+case DeclaratorContext::TemplateArgContext:
 case DeclaratorContext::TemplateTypeArgContext:
 case DeclaratorContext::TrailingReturnContext:
 case DeclaratorContext::TrailingReturnVarContext:
@@ -2082,6 +2087,7 @@ public:
 case DeclaratorContext::BlockLiteralContext:
 case DeclaratorContext::LambdaExprContext:
 case DeclaratorContext::ConversionIdContext:
+case DeclaratorContext::TemplateArgContext:
 case DeclaratorContext::TemplateTypeArgContext:
 case DeclaratorContext::TrailingReturnContext:
   return false;
@@ -2291,6 +2297,7 @@ public:
 case DeclaratorContext::BlockLiteralContext:
 case DeclaratorContext::LambdaExprContext:
 case DeclaratorContext::ConversionIdContext:
+case DeclaratorContext::TemplateArgContext:
 case DeclaratorContext::TemplateTypeArgContext:
 case DeclaratorContext::TrailingReturnContext:
 case DeclaratorContext::TrailingReturnVarContext:
@@ -2326,13 +2333,14 @@ public:
 case DeclaratorContext::ConversionIdContext:
 case DeclaratorContext::TrailingReturnContext:
 case DeclaratorContext::TrailingReturnVarContext:
+case DeclaratorContext::TemplateTypeArgContext:
   return false;
 
 case DeclaratorContext::BlockContext:
 case DeclaratorContext::ForContext:
 case DeclaratorContext::InitStmtContext:
 case DeclaratorContext::ConditionContext:
-case DeclaratorContext::TemplateTypeArgContext:
+case DeclaratorContext::TemplateArgContext:
   return 

[PATCH] D43852: [OpenMP] Extend NVPTX SPMD implementation of combined constructs

2018-02-27 Thread Carlo Bertolli via Phabricator via cfe-commits
carlo.bertolli created this revision.
carlo.bertolli added a reviewer: ABataev.
Herald added subscribers: guansong, jholewinski.

This patch extends the SPMD implementation to all target constructs and guards 
this implementation under a new flag.


Repository:
  rC Clang

https://reviews.llvm.org/D43852

Files:
  include/clang/Basic/LangOptions.def
  include/clang/Driver/Options.td
  lib/CodeGen/CGOpenMPRuntimeNVPTX.cpp
  lib/CodeGen/CGStmtOpenMP.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/OpenMP/nvptx_target_parallel_codegen.cpp
  test/OpenMP/nvptx_target_parallel_num_threads_codegen.cpp
  test/OpenMP/nvptx_target_parallel_proc_bind_codegen.cpp
  test/OpenMP/nvptx_target_parallel_reduction_codegen.cpp
  test/OpenMP/nvptx_target_simd_codegen.cpp
  test/OpenMP/nvptx_target_teams_distribute_parallel_for_codegen.cpp
  test/OpenMP/nvptx_target_teams_distribute_parallel_for_simd_codegen.cpp
  test/OpenMP/nvptx_target_teams_distribute_simd_codegen.cpp
  test/OpenMP/target_parallel_debug_codegen.cpp
  test/OpenMP/target_parallel_for_debug_codegen.cpp

Index: test/OpenMP/target_parallel_for_debug_codegen.cpp
===
--- test/OpenMP/target_parallel_for_debug_codegen.cpp
+++ test/OpenMP/target_parallel_for_debug_codegen.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
-// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -debug-info-kind=limited | FileCheck %s
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -fopenmp-cuda-mode -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -fopenmp-cuda-mode -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -debug-info-kind=limited | FileCheck %s
 // expected-no-diagnostics
 
 int main() {
Index: test/OpenMP/target_parallel_debug_codegen.cpp
===
--- test/OpenMP/target_parallel_debug_codegen.cpp
+++ test/OpenMP/target_parallel_debug_codegen.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
-// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -debug-info-kind=limited | FileCheck %s
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -fopenmp-cuda-mode -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -DCK1 -verify -fopenmp -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -fopenmp-cuda-mode -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - -debug-info-kind=limited | FileCheck %s
 // expected-no-diagnostics
 
 int main() {
Index: test/OpenMP/nvptx_target_teams_distribute_simd_codegen.cpp
===
--- /dev/null
+++ test/OpenMP/nvptx_target_teams_distribute_simd_codegen.cpp
@@ -0,0 +1,99 @@
+// Test target codegen - host bc file has to be created first.
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple powerpc64le-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm-bc %s -o %t-ppc-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx64-unknown-unknown -fopenmp-targets=nvptx64-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-ppc-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-64
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple i386-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm-bc %s -o %t-x86-host.bc
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-cuda-mode -fexceptions -fcxx-exceptions -x c++ -triple nvptx-unknown-unknown -fopenmp-targets=nvptx-nvidia-cuda -emit-llvm %s -fopenmp-is-device -fopenmp-host-ir-file-path %t-x86-host.bc -o - | FileCheck %s --check-prefix CHECK --check-prefix CHECK-32
+// expected-no-diagnostics
+#ifndef HEADER
+#define HEADER
+
+// Check that the execution mode o

[PATCH] D43847: [clang-tidy] Add check: replace string::find(...) == 0 with absl::StartsWith

2018-02-27 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added a comment.

std::basic_string::starts_with() was suggested for C++20. May be will be good 
idea to generalize code to create absl and modernize checks?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D43847



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


[PATCH] D43847: [tidy] Add check: replace string::find(...) == 0 with absl::StartsWith

2018-02-27 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added a comment.

Please add new module in docs/clang-tidy/index.rst and mention it in release 
notes.




Comment at: clang-tidy/absl/AbslTidyModule.cpp:14
+#include "StringFindStartswithCheck.h"
+using namespace clang::ast_matchers;
+

Please separate with empty line.



Comment at: clang-tidy/absl/StringFindStartswithCheck.cpp:40
+void StringFindStartswithCheck::check(const MatchFinder::MatchResult &result) {
+  const auto &context = *result.Context;
+  const auto &source = context.getSourceManager();

Please don't use auto when type could not be deduced from same statement. Same 
in other places.



Comment at: clang-tidy/absl/StringFindStartswithCheck.h:30
+private:
+  std::unique_ptr include_inserter_;
+};

Please include 



Comment at: docs/ReleaseNotes.rst:63
+
+  Checks whether a string::find result is compared with 0, and suggests
+  replacing with absl::StartsWith.

string::find -> std::string::find(), absl::StartsWith -> absl::StartsWith(). 
Please enclose them in ``.



Comment at: docs/clang-tidy/checks/absl-string-find-startswith.rst:6
+
+This check triggers on (in)equality comparisons between string.find()
+and zero. Comparisons like this should be replaced with

Please make first statement same as in release notes and avoid //This check//.



Comment at: docs/clang-tidy/checks/absl-string-find-startswith.rst:11
+
+::
+

Please use .. code-block: c++



Comment at: docs/clang-tidy/checks/absl-string-find-startswith.rst:17
+should be replaced with
+``if (absl::StartsWith(s, "Hello World")) { /* do something */ };``
+

Please use .. code-block: c++



Comment at: docs/clang-tidy/checks/absl-string-find-startswith.rst:18
+``if (absl::StartsWith(s, "Hello World")) { /* do something */ };``
+

Is there any online documentation about such usage? If so please refer to in 
at. See other guidelines as example.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D43847



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


r326295 - [analyzer] [tests] Write to logfile instead of stdout while updating

2018-02-27 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Feb 27 17:55:23 2018
New Revision: 326295

URL: http://llvm.org/viewvc/llvm-project?rev=326295&view=rev
Log:
[analyzer] [tests] Write to logfile instead of stdout while updating

reference results

Modified:
cfe/trunk/utils/analyzer/SATestUpdateDiffs.py

Modified: cfe/trunk/utils/analyzer/SATestUpdateDiffs.py
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/analyzer/SATestUpdateDiffs.py?rev=326295&r1=326294&r2=326295&view=diff
==
--- cfe/trunk/utils/analyzer/SATestUpdateDiffs.py (original)
+++ cfe/trunk/utils/analyzer/SATestUpdateDiffs.py Tue Feb 27 17:55:23 2018
@@ -13,10 +13,10 @@ import sys
 Verbose = 1
 
 
-def runCmd(Command):
+def runCmd(Command, **kwargs):
 if Verbose:
 print "Executing %s" % Command
-check_call(Command, shell=True)
+check_call(Command, shell=True, **kwargs)
 
 
 def updateReferenceResults(ProjName, ProjBuildMode):
@@ -34,27 +34,28 @@ def updateReferenceResults(ProjName, Pro
  "previously run?"
 sys.exit(1)
 
-# Remove reference results: in git, and then again for a good measure
-# with rm, as git might not remove things fully if there are empty
-# directories involved.
-runCmd('git rm -r -q "%s"' % (RefResultsPath,))
-runCmd('rm -rf "%s"' % (RefResultsPath,))
-
-# Replace reference results with a freshly computed once.
-runCmd('cp -r "%s" "%s"' % (CreatedResultsPath, RefResultsPath,))
-
-# Run cleanup script.
 BuildLogPath = SATestBuild.getBuildLogPath(RefResultsPath)
 with open(BuildLogPath, "wb+") as PBuildLogFile:
+# Remove reference results: in git, and then again for a good measure
+# with rm, as git might not remove things fully if there are empty
+# directories involved.
+runCmd('git rm -r -q "%s"' % (RefResultsPath,), stdout=PBuildLogFile)
+runCmd('rm -rf "%s"' % (RefResultsPath,), stdout=PBuildLogFile)
+
+# Replace reference results with a freshly computed once.
+runCmd('cp -r "%s" "%s"' % (CreatedResultsPath, RefResultsPath,),
+   stdout=PBuildLogFile)
+
+# Run cleanup script.
 SATestBuild.runCleanupScript(ProjDir, PBuildLogFile)
 
-SATestBuild.normalizeReferenceResults(
-ProjDir, RefResultsPath, ProjBuildMode)
+SATestBuild.normalizeReferenceResults(
+ProjDir, RefResultsPath, ProjBuildMode)
 
-# Clean up the generated difference results.
-SATestBuild.cleanupReferenceResults(RefResultsPath)
+# Clean up the generated difference results.
+SATestBuild.cleanupReferenceResults(RefResultsPath)
 
-runCmd('git add "%s"' % (RefResultsPath,))
+runCmd('git add "%s"' % (RefResultsPath,), stdout=PBuildLogFile)
 
 
 def main(argv):


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


[PATCH] D43847: [tidy] Add check: replace string::find(...) == 0 with absl::StartsWith

2018-02-27 Thread Niko Weh via Phabricator via cfe-commits
niko created this revision.
niko added reviewers: ioeric, hokein.
Herald added subscribers: cfe-commits, mgorny.

Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D43847

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/absl/AbslTidyModule.cpp
  clang-tidy/absl/CMakeLists.txt
  clang-tidy/absl/StringFindStartswithCheck.cpp
  clang-tidy/absl/StringFindStartswithCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/absl-string-find-startswith.rst
  docs/clang-tidy/checks/list.rst
  test/clang-tidy/absl-string-find-startswith.cpp

Index: test/clang-tidy/absl-string-find-startswith.cpp
===
--- test/clang-tidy/absl-string-find-startswith.cpp
+++ test/clang-tidy/absl-string-find-startswith.cpp
@@ -0,0 +1,49 @@
+// RUN: %check_clang_tidy %s absl-string-find-startswith %t -- -- -I%S
+// -std=c++11
+
+namespace std {
+template  class allocator {};
+template  class char_traits {};
+template ,
+  typename A = std::allocator>
+struct basic_string {
+  basic_string();
+  basic_string(const basic_string &);
+  basic_string(const C *, const A &a = A());
+  ~basic_string();
+  int find(basic_string s, int pos = 0);
+  int find(const char *s, int pos = 0);
+};
+typedef basic_string string;
+typedef basic_string wstring;
+} // namespace std
+
+std::string foo(std::string);
+std::string bar();
+
+void tests(std::string s) {
+  s.find("a") == 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Use absl::StartsWith instead of
+  // find() == 0 [absl-string-find-startswith] CHECK_FIXES:
+  // {{^}}absl::StartsWith(s, "a");{{$}}
+
+  s.find(s) == 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Use absl::StartsWith instead of
+  // find() == 0 [absl-string-find-startswith] CHECK_FIXES:
+  // {{^}}absl::StartsWith(s, s);{{$}}
+
+  s.find("aaa") != 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Use !absl::StartsWith instead of
+  // find() != 0 [absl-string-find-startswith] CHECK_FIXES:
+  // {{^}}!absl::StartsWith(s, "aaa");{{$}}
+
+  s.find(foo(foo(bar( != 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Use !absl::StartsWith instead of
+  // find() != 0 [absl-string-find-startswith] CHECK_FIXES:
+  // {{^}}!absl::StartsWith(s, foo(foo(foo)));{{$}}
+
+  // expressions that don't trigger the check are here.
+  s.find("a", 1) == 0;
+  s.find("a", 1) == 1;
+  s.find("a") == 1;
+}
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -4,6 +4,7 @@
 =
 
 .. toctree::
+   absl-string-find-startswith
android-cloexec-accept
android-cloexec-accept4
android-cloexec-creat
Index: docs/clang-tidy/checks/absl-string-find-startswith.rst
===
--- docs/clang-tidy/checks/absl-string-find-startswith.rst
+++ docs/clang-tidy/checks/absl-string-find-startswith.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - absl-string-find-startswith
+
+absl-string-find-startswith
+==
+
+This check triggers on (in)equality comparisons between string.find()
+and zero. Comparisons like this should be replaced with
+absl::StartsWith(string, prefix). This is both a readability and a
+performance issue.
+
+::
+
+string s = "...";
+if (s.find("Hello World") == 0) { /* do something */ }
+
+should be replaced with
+``if (absl::StartsWith(s, "Hello World")) { /* do something */ };``
+
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -57,6 +57,12 @@
 Improvements to clang-tidy
 --
 
+- New `absl-string-find-startswith
+  `_ check
+
+  Checks whether a string::find result is compared with 0, and suggests
+  replacing with absl::StartsWith.
+
 - New `fuchsia-statically-constructed-objects
   `_ check
 
Index: clang-tidy/tool/ClangTidyMain.cpp
===
--- clang-tidy/tool/ClangTidyMain.cpp
+++ clang-tidy/tool/ClangTidyMain.cpp
@@ -462,6 +462,11 @@
 static int LLVM_ATTRIBUTE_UNUSED CERTModuleAnchorDestination =
 CERTModuleAnchorSource;
 
+// This anchor is used to force the linker to link the AbslModule.
+extern volatile int AbslModuleAnchorSource;
+static int LLVM_ATTRIBUTE_UNUSED AbslModuleAnchorDestination =
+AbslModuleAnchorSource;
+
 // This anchor is used to force the linker to link the BoostModule.
 extern volatile int BoostModuleAnchorSource;
 static int LLVM_ATTRIBUTE_UNUSED BoostModuleAnchorDestination =
Index: clang-tidy/tool/CMakeLists.txt

r326292 - [StaticAnalyzer] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).

2018-02-27 Thread Eugene Zelenko via cfe-commits
Author: eugenezelenko
Date: Tue Feb 27 17:10:04 2018
New Revision: 326292

URL: http://llvm.org/viewvc/llvm-project?rev=326292&view=rev
Log:
[StaticAnalyzer] Fix some Clang-tidy modernize and Include What You Use 
warnings; other minor fixes (NFC).

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h

cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/Environment.h
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/FunctionSummary.h
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ConstraintManager.cpp
cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
cfe/trunk/lib/StaticAnalyzer/Core/Environment.cpp
cfe/trunk/lib/StaticAnalyzer/Core/FunctionSummary.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h?rev=326292&r1=326291&r2=326292&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h Tue 
Feb 27 17:10:04 2018
@@ -1,4 +1,4 @@
-//===- CallEvent.h - Wrapper for all function and method calls *- C++ 
-*--//
+//===- CallEvent.h - Wrapper for all function and method calls --*- C++ 
-*-===//
 //
 // The LLVM Compiler Infrastructure
 //
@@ -16,19 +16,42 @@
 #ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
 #define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_CALLEVENT_H
 
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclObjC.h"
+#include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
-#include "clang/Analysis/AnalysisDeclContext.h"
+#include "clang/AST/Stmt.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/PointerIntPair.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Allocator.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/ErrorHandling.h"
+#include 
+#include 
 #include 
 
 namespace clang {
+
+class LocationContext;
 class ProgramPoint;
 class ProgramPointTag;
+class StackFrameContext;
 
 namespace ento {
 
@@ -48,19 +71,20 @@ enum CallEventKind {
 };
 
 class CallEvent;
-class CallEventManager;
 
 /// This class represents a description of a function call using the number of
 /// arguments and the name of the function.
 class CallDescription {
   friend CallEvent;
-  mutable IdentifierInfo *II;
-  mutable bool IsLookupDone;
+
+  mutable IdentifierInfo *II = nullptr;
+  mutable bool IsLookupDone = false;
   StringRef FuncName;
   unsigned RequiredArgs;
 
 public:
-  const static unsigned NoArgRequirement = ~0;
+  const static unsigned NoArgRequirement = 
std::numeric_limits::max();
+
   /// \brief Constructs a CallDescription object.
   ///
   /// @param FuncName The name of the function that will be matched.
@@ -69,8 +93,7 @@ public:
   /// call. Omit this parameter to match every occurance of call with a given
   /// name regardless the number of arguments.
   CallDescription(StringRef FuncName, unsigned RequiredArgs = NoArgRequirement)
-  : II(nullptr), IsLookupDone(false), FuncName(FuncName),
-RequiredArgs(RequiredArgs) {}
+  : FuncName(FuncName), RequiredArgs(RequiredArgs) {}
 
   /// \brief Get the name of the function that this object matches.
   StringRef getFunctionName() const { return FuncName; }
@@ -104,18 +127,19 @@ public:
 class RuntimeDefinition {
   /// The Declaration of the function which could be called at runtime.
   /// NULL if not available.
-  const Decl *D;
+  const Decl *D = nullptr;
 
   /// The region representing an object (ObjC/C++) on which the method is
   /// called. With dynamic dispatch, the method definition depends on the
   /// runtime type of this object. NULL when the DynamicTypeInfo is
   /// precise.
-  const MemRegion *R;
+  const MemRegion *R = nullptr;
 
 public:
-  RuntimeDefinition(): D(nullptr), R(nullptr) {}
-  RuntimeDefinition(const Decl *InD): D(InD), R(nullptr) {}
+  RuntimeDefinition() = default;
+  RuntimeDefinition(const Decl *InD): D(InD) {}
   Runt

Buildbot numbers for the week of 2/18/2018 - 2/24/2018

2018-02-27 Thread Galina Kistanova via cfe-commits
Hello everyone,

Below are some buildbot numbers for the last week of 2/18/2018 - 2/24/2018.

Please see the same data in attached csv files:

The longest time each builder was red during the week;
"Status change ratio" by active builder (percent of builds that changed the
builder status from greed to red or from red to green);
Count of commits by project;
Number of completed builds, failed builds and average build time for
successful builds per active builder;
Average waiting time for a revision to get build result per active builder
(response time).

Thanks

Galina


The longest time each builder was red during the week:

buildername| was_red
---+-
 libcxx-libcxxabi-x86_64-linux-debian-noexceptions | 53:09:40
 lldb-x86_64-darwin-13.4   | 49:15:31
 lldb-x86_64-ubuntu-14.04-android  | 45:11:49
 llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast  | 25:52:21
 clang-cmake-thumbv7-a15-full-sh   | 17:47:30
 libcxx-libcxxabi-libunwind-aarch64-linux  | 17:40:32
 clang-cmake-armv7-a15-selfhost-neon   | 16:18:54
 clang-cmake-aarch64-quick | 15:43:08
 clang-cmake-armv7-a15 | 15:10:30
 clang-hexagon-elf | 15:04:48
 clang-cmake-aarch64-global-isel   | 15:03:09
 clang-cmake-aarch64-full  | 14:40:52
 clang-cmake-armv7-a15-full| 14:32:26
 sanitizer-x86_64-linux-bootstrap-msan | 13:37:48
 llvm-clang-x86_64-expensive-checks-win| 13:19:18
 lld-x86_64-darwin13   | 10:38:24
 clang-lld-x86_64-2stage   | 10:03:08
 llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast| 08:43:58
 clang-cmake-armv7-a15-selfhost| 08:32:41
 llvm-mips-linux   | 08:07:07
 clang-s390x-linux-multistage  | 07:50:05
 clang-s390x-linux | 07:14:06
 clang-cmake-aarch64-lld   | 06:49:28
 sanitizer-ppc64be-linux   | 06:45:56
 clang-with-lto-ubuntu | 06:32:35
 clang-with-thin-lto-ubuntu| 06:04:23
 sanitizer-ppc64le-linux   | 06:00:39
 clang-ppc64be-linux-multistage| 05:54:12
 sanitizer-x86_64-linux| 05:48:02
 clang-ppc64le-linux-multistage| 05:46:41
 clang-ppc64le-linux-lnt   | 05:32:03
 clang-ppc64be-linux   | 05:29:28
 clang-atom-d525-fedora-rel| 05:27:20
 clang-ppc64le-linux   | 05:22:27
 clang-x86_64-debian-fast  | 05:13:29
 clang-bpf-build   | 05:07:13
 lldb-windows7-android | 04:27:01
 perf-x86_64-penryn-O3-polly-parallel-fast | 03:35:27
 perf-x86_64-penryn-O3-polly-unprofitable  | 03:28:29
 clang-s390x-linux-lnt | 03:27:11
 clang-cuda-build  | 03:02:36
 clang-x86_64-linux-abi-test   | 02:53:22
 sanitizer-x86_64-linux-bootstrap  | 02:25:51
 sanitizer-x86_64-linux-bootstrap-ubsan| 02:05:34
 clang-native-arm-lnt  | 02:05:27
 polly-amd64-linux | 01:40:27
 lldb-amd64-ninja-netbsd8  | 01:34:17
 sanitizer-x86_64-linux-android| 01:28:57
 lldb-x86-windows-msvc2015 | 01:27:47
 lldb-x86_64-ubuntu-14.04-cmake| 01:20:06
 sanitizer-x86_64-linux-fuzzer | 01:19:10
 lldb-x86_64-ubuntu-14.04-buildserver  | 01:18:56
 sanitizer-x86_64-linux-autoconf   | 01:11:53
 sanitizer-x86_64-linux-fast   | 01:10:26
 clang-cmake-x86_64-avx2-linux | 01:09:11
 clang-cmake-x86_64-avx2-linux-perf| 01:05:41
 lld-perf-testsuite| 01:02:15
 sanitizer-windows | 00:55:39
 lldb-amd64-ninja-freebsd11| 00:55:27
 clang-cmake-x86_64-sde-avx512-linux   | 00:52:02
 llvm-hexagon-elf  | 00:49:43
 reverse-iteration | 00:44:45
 lld-x86_64-freebsd| 00:23:59
 lld-x86_64-win7   | 00:23:58
 polly-arm-linux   | 00:23:43
(65 rows)


"Status change ratio" by active builder (percent of builds that changed the
builder status from greed to red or from red to green):

   buildername   | builds | c

Buildbot numbers for the week of 2/11/2018 - 2/17/2018

2018-02-27 Thread Galina Kistanova via cfe-commits
Hello everyone,

Below are some buildbot numbers for the week of 2/11/2018 - 2/17/2018.

Please see the same data in attached csv files:

The longest time each builder was red during the week;
"Status change ratio" by active builder (percent of builds that changed the
builder status from greed to red or from red to green);
Count of commits by project;
Number of completed builds, failed builds and average build time for
successful builds per active builder;
Average waiting time for a revision to get build result per active builder
(response time).

Thanks

Galina


The longest time each builder was red during the week:

   buildername   |  was_red
-+--
 lldb-x86_64-darwin-13.4 | 103:40:05
 libcxx-libcxxabi-x86_64-linux-debian-noexceptions   | 83:30:42
 libcxx-libcxxabi-x86_64-linux-ubuntu-gcc-tot-latest-std | 77:08:58
 clang-x86-windows-msvc2015  | 40:45:33
 clang-x64-ninja-win7| 38:28:36
 perf-x86_64-penryn-O3-polly-unprofitable| 37:20:29
 lldb-x86_64-ubuntu-14.04-cmake  | 25:38:40
 clang-tools-sphinx-docs | 25:33:37
 lldb-x86_64-ubuntu-14.04-android| 25:03:13
 lldb-windows7-android   | 24:02:33
 llvm-clang-x86_64-expensive-checks-win  | 22:28:57
 clang-hexagon-elf   | 17:49:42
 clang-cmake-thumbv7-a15-full-sh | 17:25:56
 clang-cmake-armv7-a15   | 15:37:38
 clang-cmake-armv7-a15-selfhost-neon | 15:09:03
 clang-cmake-armv7-a15-full  | 14:38:10
 clang-cmake-armv7-a15-selfhost  | 14:31:07
 libcxx-libcxxabi-libunwind-x86_64-linux-debian  | 13:00:19
 libcxx-libcxxabi-singlethreaded-x86_64-linux-debian | 12:47:21
 clang-bpf-build | 09:29:36
 llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast| 07:28:49
 clang-lld-x86_64-2stage | 05:49:13
 clang-native-arm-lnt| 05:43:34
 clang-s390x-linux   | 05:09:47
 clang-with-lto-ubuntu   | 04:54:47
 lldb-x86-windows-msvc2015   | 04:40:49
 clang-with-thin-lto-ubuntu  | 04:20:49
 sanitizer-x86_64-linux-bootstrap-msan   | 04:12:57
 perf-x86_64-penryn-O3-polly-parallel-fast   | 04:12:55
 clang-x86_64-linux-abi-test | 04:06:39
 llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast  | 04:04:38
 llvm-mips-linux | 04:04:01
 sanitizer-x86_64-linux-fast | 04:00:50
 sanitizer-x86_64-linux  | 03:50:15
 clang-s390x-linux-lnt   | 03:45:15
 polly-amd64-linux   | 03:30:48
 clang-x86_64-debian-fast| 03:29:38
 sanitizer-windows   | 03:19:22
 clang-cmake-aarch64-full| 03:15:57
 sanitizer-ppc64le-linux | 03:15:51
 sanitizer-x86_64-linux-bootstrap| 03:13:19
 clang-cmake-aarch64-lld | 03:02:26
 clang-ppc64le-linux-lnt | 02:57:32
 clang-ppc64be-linux-multistage  | 02:40:15
 clang-ppc64le-linux-multistage  | 02:31:16
 sanitizer-x86_64-linux-bootstrap-ubsan  | 02:17:32
 sanitizer-ppc64be-linux | 02:14:57
 clang-cmake-aarch64-quick   | 02:14:54
 clang-cuda-build| 02:12:00
 lld-perf-testsuite  | 02:10:56
 clang-cmake-aarch64-global-isel | 02:07:16
 clang-ppc64le-linux | 01:57:03
 sanitizer-x86_64-linux-android  | 01:51:28
 clang-atom-d525-fedora-rel  | 01:50:50
 clang-ppc64be-linux | 01:46:46
 clang-cmake-x86_64-sde-avx512-linux | 01:44:56
 lldb-amd64-ninja-netbsd8| 01:42:03
 clang-cmake-x86_64-avx2-linux   | 01:32:23
 reverse-iteration   | 01:29:45
 lldb-x86_64-ubuntu-14.04-buildserver| 01:22:30
 sanitizer-x86_64-linux-fuzzer   | 01:19:24
 clang-cmake-x86_64-avx2-linux-perf  | 01:10:25
 lld-x86_64-darwin

Buildbot numbers for the week of 2/04/2018 - 2/10/2018

2018-02-27 Thread Galina Kistanova via cfe-commits
Hello everyone,

Below are some buildbot numbers for the week of 2/04/2018 - 2/10/2018.

Please see the same data in attached csv files:

The longest time each builder was red during the week;
"Status change ratio" by active builder (percent of builds that changed the
builder status from greed to red or from red to green);
Count of commits by project;
Number of completed builds, failed builds and average build time for
successful builds per active builder;
Average waiting time for a revision to get build result per active builder
(response time).

Thanks

Galina


The longest time each builder was red during the week:

  buildername  | was_red
---+-
 lldb-windows7-android | 69:49:34
 clang-x64-ninja-win7  | 52:37:06
 clang-x86-windows-msvc2015| 52:07:49
 clang-cuda-build  | 49:45:31
 libcxx-libcxxabi-x86_64-linux-ubuntu-gcc49-cxx11  | 42:25:39
 lldb-amd64-ninja-netbsd8  | 39:16:15
 llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast  | 23:42:19
 clang-tools-sphinx-docs   | 21:45:55
 llvm-mips-linux   | 19:15:51
 ubuntu-gcc7.1-werror  | 15:08:05
 clang-s390x-linux-multistage  | 14:40:19
 clang-lld-x86_64-2stage   | 14:10:11
 clang-with-lto-ubuntu | 13:33:08
 clang-with-thin-lto-ubuntu| 12:39:05
 sanitizer-x86_64-linux| 12:31:03
 lldb-x86_64-ubuntu-14.04-android  | 12:02:25
 lldb-x86-windows-msvc2015 | 11:57:33
 lld-x86_64-darwin13   | 11:27:08
 sanitizer-ppc64le-linux   | 11:24:31
 sanitizer-ppc64be-linux   | 09:50:05
 libcxx-libcxxabi-x86_64-linux-ubuntu-cxx17| 08:43:42
 llvm-clang-x86_64-expensive-checks-win| 08:11:16
 clang-cmake-armv7-a15-selfhost-neon   | 07:25:02
 clang-cmake-armv7-a15-selfhost| 07:17:27
 lldb-x86_64-darwin-13.4   | 07:02:56
 clang-cmake-thumbv7-a15-full-sh   | 06:38:23
 clang-ppc64le-linux-multistage| 05:10:41
 clang-s390x-linux-lnt | 04:59:55
 clang-s390x-linux | 04:57:29
 clang-cmake-armv7-a15-full| 04:48:48
 clang-cmake-aarch64-full  | 03:51:12
 clang-cmake-aarch64-quick | 03:43:29
 clang-cmake-aarch64-global-isel   | 03:43:10
 sanitizer-x86_64-linux-bootstrap-msan | 03:37:38
 clang-atom-d525-fedora-rel| 03:27:40
 sanitizer-x86_64-linux-bootstrap  | 03:25:15
 clang-cmake-armv7-a15 | 03:18:39
 clang-hexagon-elf | 03:17:49
 llvm-hexagon-elf  | 03:06:18
 clang-cmake-aarch64-lld   | 02:58:00
 clang-x86_64-linux-selfhost-modules-2 | 02:54:36
 clang-ppc64be-linux   | 02:49:55
 clang-ppc64le-linux   | 02:42:48
 clang-bpf-build   | 02:42:39
 libcxx-libcxxabi-x86_64-linux-debian  | 02:40:57
 libcxx-libcxxabi-x86_64-linux-ubuntu-32bit| 02:37:15
 clang-x86_64-debian-fast  | 02:33:02
 sanitizer-x86_64-linux-bootstrap-ubsan| 02:18:02
 clang-ppc64le-linux-lnt   | 02:14:19
 clang-ppc64be-linux-multistage| 02:10:09
 libcxx-libcxxabi-x86_64-linux-debian-noexceptions | 02:09:45
 libcxx-libcxxabi-singlethreaded-x86_64-linux-debian   | 02:09:28
 sanitizer-x86_64-linux-fuzzer | 02:06:06
 reverse-iteration | 02:05:03
 sanitizer-windows | 02:04:59
 libcxx-libcxxabi-libunwind-x86_64-linux-debian| 02:00:10
 sanitizer-x86_64-linux-fast   | 01:59:54
 lld-x86_64-win7   | 01:54:08
 lldb-x86_64-ubuntu-14.04-buildserver  | 01:42:10
 clang-cmake-x86_64-avx2-linux-perf| 01:37:25
 llvm-clang-lld-x86_64-scei-ps4-ubuntu-fast| 01:34:00
 clang-cmake-x86_64-avx2-linux | 01:31:47
 lldb-x86_64-ubuntu-14.04-cmake| 01:30:57
 libcxx-libcxxabi-libunwind-aarch64-linux-noexceptions | 01:29:33
 perf-x86_64-penr

[PATCH] D43842: CodeGenObjCXX: handle inalloca appropriately for msgSend variant

2018-02-27 Thread Saleem Abdulrasool via Phabricator via cfe-commits
compnerd created this revision.
compnerd added reviewers: rjmccall, rnk.

objc_msgSend_stret takes a hidden parameter for the returned structure's
address for the construction.  When the function signature is rewritten
for the inalloca passing, the return type is no longer marked as
indirect but rather inalloca stret.  This enhances the test for the
indirect return to check for that case as well.  This fixes the
incorrect return classification for Windows x86.


Repository:
  rC Clang

https://reviews.llvm.org/D43842

Files:
  lib/CodeGen/CGCall.cpp
  test/CodeGenObjCXX/msabi-stret.mm


Index: test/CodeGenObjCXX/msabi-stret.mm
===
--- /dev/null
+++ test/CodeGenObjCXX/msabi-stret.mm
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fobjc-runtime=ios-6.0 
-Os -S -emit-llvm -o - %s -mdisable-fp-elim | FileCheck %s
+
+struct S {
+  S() = default;
+  S(const S &) {}
+};
+
+@interface I
++ (S)m:(S)s;
+@end
+
+S f() {
+  return [I m:S()];
+}
+
+// CHECK: declare dllimport void @objc_msgSend_stret(i8*, i8*, ...)
+// CHECK-NOT: declare dllimport void @objc_msgSend(i8*, i8*, ...)
+
Index: lib/CodeGen/CGCall.cpp
===
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1479,7 +1479,8 @@
 /***/
 
 bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) {
-  return FI.getReturnInfo().isIndirect();
+  const auto &RI = FI.getReturnInfo();
+  return RI.isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
 }
 
 bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) {


Index: test/CodeGenObjCXX/msabi-stret.mm
===
--- /dev/null
+++ test/CodeGenObjCXX/msabi-stret.mm
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple i686-unknown-windows-msvc -fobjc-runtime=ios-6.0 -Os -S -emit-llvm -o - %s -mdisable-fp-elim | FileCheck %s
+
+struct S {
+  S() = default;
+  S(const S &) {}
+};
+
+@interface I
++ (S)m:(S)s;
+@end
+
+S f() {
+  return [I m:S()];
+}
+
+// CHECK: declare dllimport void @objc_msgSend_stret(i8*, i8*, ...)
+// CHECK-NOT: declare dllimport void @objc_msgSend(i8*, i8*, ...)
+
Index: lib/CodeGen/CGCall.cpp
===
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1479,7 +1479,8 @@
 /***/
 
 bool CodeGenModule::ReturnTypeUsesSRet(const CGFunctionInfo &FI) {
-  return FI.getReturnInfo().isIndirect();
+  const auto &RI = FI.getReturnInfo();
+  return RI.isIndirect() || (RI.isInAlloca() && RI.getInAllocaSRet());
 }
 
 bool CodeGenModule::ReturnSlotInterferesWithArgs(const CGFunctionInfo &FI) {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r326278 - AMDGPU: Move run and check lines around to match processor order in AMDGPU.h

2018-02-27 Thread Konstantin Zhuravlyov via cfe-commits
Author: kzhuravl
Date: Tue Feb 27 16:27:00 2018
New Revision: 326278

URL: http://llvm.org/viewvc/llvm-project?rev=326278&view=rev
Log:
AMDGPU: Move run and check lines around to match processor order in AMDGPU.h

Modified:
cfe/trunk/test/Driver/amdgpu-mcpu.cl

Modified: cfe/trunk/test/Driver/amdgpu-mcpu.cl
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/amdgpu-mcpu.cl?rev=326278&r1=326277&r2=326278&view=diff
==
--- cfe/trunk/test/Driver/amdgpu-mcpu.cl (original)
+++ cfe/trunk/test/Driver/amdgpu-mcpu.cl Tue Feb 27 16:27:00 2018
@@ -27,9 +27,9 @@
 // RUN: %clang -### -target r600 -mcpu=sumo2 %s 2>&1 | FileCheck 
--check-prefix=SUMO %s
 // RUN: %clang -### -target r600 -mcpu=barts %s 2>&1 | FileCheck 
--check-prefix=BARTS %s
 // RUN: %clang -### -target r600 -mcpu=caicos %s 2>&1 | FileCheck 
--check-prefix=CAICOS %s
-// RUN: %clang -### -target r600 -mcpu=turks %s 2>&1 | FileCheck 
--check-prefix=TURKS %s
 // RUN: %clang -### -target r600 -mcpu=aruba %s 2>&1 | FileCheck 
--check-prefix=CAYMAN %s
 // RUN: %clang -### -target r600 -mcpu=cayman %s 2>&1 | FileCheck 
--check-prefix=CAYMAN %s
+// RUN: %clang -### -target r600 -mcpu=turks %s 2>&1 | FileCheck 
--check-prefix=TURKS %s
 
 // R600:"-target-cpu" "r600"
 // R630:"-target-cpu" "r630"
@@ -45,8 +45,8 @@
 // SUMO:"-target-cpu" "sumo"
 // BARTS:   "-target-cpu" "barts"
 // CAICOS:  "-target-cpu" "caicos"
-// TURKS:   "-target-cpu" "turks"
 // CAYMAN:  "-target-cpu" "cayman"
+// TURKS:   "-target-cpu" "turks"
 
 //
 // AMDGCN-based processors.


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


[PATCH] D43841: Add an option to disable tail-call optimization for escaping blocks

2018-02-27 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak created this revision.
ahatanak added a reviewer: rjmccall.

This patch adds a command line option (-fdisable-tail-calls-esca
ping-blocks) that annotates escaping block invoke functions with attribute 
"disable-tail-calls". This is an option that helps users in debugging their 
code who spend a lot of time trying to figure out where a block came from.

The user who is asking for this command line option does not want to disable 
tail-call optimization for non-escaping blocks. For example, in the following 
code, we should not disable tail-call optimization for the block that is 
directly passed to function "noescapefunc":

  void foo3(void);
  
  void foo1() {
noescapefunc(^{ foo3(); }); // do not disable tail-call.
BlockTy b = ^{ foo3(); }; // disable tail-call.
noescapefunc(b);
  }

Ideally, I think we want to avoid disabling tail-call optimization for block 
"b" too, as it doesn't escape. However, this patch doesn't do anything to avoid 
disabling tail-call optimization for the block, since that would require a more 
complex analysis.

rdar://problem/35758207


https://reviews.llvm.org/D43841

Files:
  include/clang/AST/DeclObjC.h
  include/clang/AST/Type.h
  include/clang/Driver/Options.td
  include/clang/Frontend/CodeGenOptions.def
  lib/AST/DeclObjC.cpp
  lib/AST/Type.cpp
  lib/CodeGen/CGCall.cpp
  lib/CodeGen/CodeGenFunction.h
  lib/CodeGen/CodeGenModule.h
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  test/CodeGenObjC/disable-tail-call-escaping-block.m
  test/Driver/fdisable-tail-calls-escaping-blocks.c

Index: test/Driver/fdisable-tail-calls-escaping-blocks.c
===
--- /dev/null
+++ test/Driver/fdisable-tail-calls-escaping-blocks.c
@@ -0,0 +1,7 @@
+// RUN: %clang -### %s -fno-disable-tail-calls-escaping-blocks -fdisable-tail-calls-escaping-blocks 2> %t
+// RUN: FileCheck --check-prefix=CHECK-DISABLE < %t %s
+// CHECK-DISABLE: "-fdisable-tail-calls-escaping-blocks"
+
+// RUN: %clang -### %s -fdisable-tail-calls-escaping-blocks -fno-disable-tail-calls-escaping-blocks 2> %t
+// RUN: FileCheck --check-prefix=CHECK-NO-DISABLE < %t %s
+// CHECK-NO-DISABLE-NOT: "-fdisable-tail-calls-escaping-blocks"
Index: test/CodeGenObjC/disable-tail-call-escaping-block.m
===
--- /dev/null
+++ test/CodeGenObjC/disable-tail-call-escaping-block.m
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin -fblocks -fdisable-tail-calls-escaping-blocks -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: define void @test(
+// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE0:.*]] to i8*)
+// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE1:.*]] to i8*)
+// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE2:.*]] to i8*)
+// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE3:.*]] to i8*)
+// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE4:.*]] to i8*)
+// CHECK: store i8* bitcast (void (i8*)* @[[TEST_BLOCK_INVOKE5:.*]] to i8*)
+
+// CHECK: define internal void @[[TEST_BLOCK_INVOKE0]]({{.*}}) #[[DISABLEATTR:.*]] {
+// CHECK: define internal void @[[TEST_BLOCK_INVOKE1]]({{.*}}) #[[ENABLEATTR:.*]] {
+// CHECK: define internal void @[[TEST_BLOCK_INVOKE2]]({{.*}}) #[[DISABLEATTR]] {
+// CHECK: define internal void @[[TEST_BLOCK_INVOKE3]]({{.*}}) #[[DISABLEATTR]] {
+// CHECK: define internal void @[[TEST_BLOCK_INVOKE4]]({{.*}}) #[[ENABLEATTR]] {
+// CHECK: define internal void @[[TEST_BLOCK_INVOKE5]]({{.*}}) #[[DISABLEATTR]] {
+
+// CHECK: attributes #[[ENABLEATTR]] = {{{.*}}"disable-tail-calls"="false"{{.*}}}
+// CHECK: attributes #[[DISABLEATTR]] = {{{.*}}"disable-tail-calls"="true"{{.*}}}
+
+typedef void (^BlockTy)(void);
+
+void callee0(__attribute__((noescape)) BlockTy);
+void callee1(BlockTy);
+
+__attribute__((objc_root_class))
+@interface C0
+-(void)m0:(__attribute__((noescape)) BlockTy)p;
+-(void)m1:(BlockTy)p;
+@end
+
+@implementation C0
+-(void)m0:(__attribute__((noescape)) BlockTy)p {}
+-(void)m1:(BlockTy)p {}
+@end
+
+void test(id a, C0 *c0) {
+  BlockTy b0 = ^{ (void)a; }; // disable tail-call optimization.
+  callee0(b0);
+  callee0(^{ (void)a; }); // enable tail-call optimization.
+  callee1(^{ (void)a; }); // disable tail-call optimization.
+
+  BlockTy b1 = ^{ (void)a; }; // disable tail-call optimization.
+  [c0 m0:b1];
+  [c0 m0:^{ (void)a; }]; // enable tail-call optimization.
+  [c0 m1:^{ (void)a; }]; // disable tail-call optimization.
+}
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -639,6 +639,8 @@
   Opts.DisableFree = Args.hasArg(OPT_disable_free);
   Opts.DiscardValueNames = Args.hasArg(OPT_discard_value_names);
   Opts.DisableTailCalls = Args.hasArg(OPT_mdisable_tail_calls);
+  Opts.DisableTailCallsEscapingBlocks =
+  Args.hasA

[PATCH] D43840: [CFG] [analyzer] Fix a crash on finding construction context for implicit constructor conversion.

2018-02-27 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ created this revision.
NoQ added reviewers: dcoughlin, xazax.hun, a.sidorin, george.karpenkov, szepet.
Herald added subscribers: cfe-commits, rnkovacs.

While landing https://reviews.llvm.org/D43428 as 
https://reviews.llvm.org/rC325966, i caused an internal compiler error of an 
MSVC 2015 compiler on a buildbot. Then i tried to hotfix it in 
https://reviews.llvm.org/rC325969 (which didn't help) and in 
https://reviews.llvm.org/rC325978 (which suddenly helped, i.e. simply moving 
the existing code around has suppressed the crash). Then i committed 
https://reviews.llvm.org/D43481 as https://reviews.llvm.org/rC326016 and MSVC 
crashed again. Then i committed https://reviews.llvm.org/rC326021 as a hotfix, 
and it seemed to help again.

The problem is, i lost some code in https://reviews.llvm.org/rC326021. Namely i 
forgot to check that the cast that's mentioned in 
https://reviews.llvm.org/D43481 / https://reviews.llvm.org/rC326016 is a 
NoOp-kind cast.

Bring back the check for the cast kind, add a test for it.

The test exposes an interesting edge case that we don't support yet: implicit 
constructor conversion. For now we only support explicit constructor conversion 
(i.e. functional cast as in https://reviews.llvm.org/D43480). For whatever 
reason, in this case the AST doesn't contain a `CXXBindTemporaryExpr` even if 
the object requires destruction, so the assertion in 
`ConstructionContext::createFromLayers` that says that any construction context 
with an MTE but without the respective BTE should be of an object with a 
trivial destructor (which isn't a problem here because the object is 
lifetime-extended anyway).


Repository:
  rC Clang

https://reviews.llvm.org/D43840

Files:
  lib/Analysis/CFG.cpp
  test/Analysis/cfg-rich-constructors.cpp


Index: test/Analysis/cfg-rich-constructors.cpp
===
--- test/Analysis/cfg-rich-constructors.cpp
+++ test/Analysis/cfg-rich-constructors.cpp
@@ -484,4 +484,35 @@
 void constructorInTernaryCondition() {
   const D &d = D(1) ? D(2) : D(3);
 }
+
 } // end namespace temporary_object_expr_with_dtors
+
+namespace implicit_constructor_conversion {
+
+class A {};
+A get();
+
+class B {
+public:
+  B(const A &);
+  ~B() {}
+};
+
+// FIXME: Find construction context for the implicit constructor conversion.
+// CHECK: void implicitConstructionConversionFromFunctionValue()
+// CHECK:  1: get
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class 
implicit_constructor_conver
+// CHECK-NEXT: 3: [B1.2]()
+// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class 
implicit_constructor_conversion::A)
+// CHECK-NEXT: 5: [B1.4]
+// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, class 
implicit_constructor_conversion::B)
+// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class 
implicit_constructor_convers
+// CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class 
implicit_constructor_conversion::B)
+// CHECK-NEXT: 9: [B1.8]
+// CHECK-NEXT:10: const implicit_constructor_conversion::B &b = get();
+// CHECK-NEXT:11: [B1.10].~B() (Implicit destructor)
+void implicitConstructionConversionFromFunctionValue() {
+  const B &b = get(); // no-crash
+}
+
+} // end namespace implicit_constructor_conversion
Index: lib/Analysis/CFG.cpp
===
--- lib/Analysis/CFG.cpp
+++ lib/Analysis/CFG.cpp
@@ -1200,7 +1200,8 @@
   }
   case Stmt::ImplicitCastExprClass: {
 auto *Cast = cast(Child);
-findConstructionContexts(Layer, Cast->getSubExpr());
+if (Cast->getCastKind() == CK_NoOp)
+  findConstructionContexts(Layer, Cast->getSubExpr());
 break;
   }
   case Stmt::CXXBindTemporaryExprClass: {


Index: test/Analysis/cfg-rich-constructors.cpp
===
--- test/Analysis/cfg-rich-constructors.cpp
+++ test/Analysis/cfg-rich-constructors.cpp
@@ -484,4 +484,35 @@
 void constructorInTernaryCondition() {
   const D &d = D(1) ? D(2) : D(3);
 }
+
 } // end namespace temporary_object_expr_with_dtors
+
+namespace implicit_constructor_conversion {
+
+class A {};
+A get();
+
+class B {
+public:
+  B(const A &);
+  ~B() {}
+};
+
+// FIXME: Find construction context for the implicit constructor conversion.
+// CHECK: void implicitConstructionConversionFromFunctionValue()
+// CHECK:  1: get
+// CHECK-NEXT: 2: [B1.1] (ImplicitCastExpr, FunctionToPointerDecay, class implicit_constructor_conver
+// CHECK-NEXT: 3: [B1.2]()
+// CHECK-NEXT: 4: [B1.3] (ImplicitCastExpr, NoOp, const class implicit_constructor_conversion::A)
+// CHECK-NEXT: 5: [B1.4]
+// CHECK-NEXT: 6: [B1.5] (CXXConstructExpr, class implicit_constructor_conversion::B)
+// CHECK-NEXT: 7: [B1.6] (ImplicitCastExpr, ConstructorConversion, class implicit_constructor_convers
+// CHECK-NEXT: 8: [B1.7] (ImplicitCastExpr, NoOp, const class implici

[PATCH] D43839: Add an option to disable tail-call optimization for escaping blocks

2018-02-27 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak abandoned this revision.
ahatanak added a comment.

I'm going to send this patch again so that people can read the summary.


https://reviews.llvm.org/D43839



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


[PATCH] D43839: Add an option to disable tail-call optimization for escaping blocks

2018-02-27 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak added a subscriber: cfe-commits.
ahatanak added a comment.

Add cfe-commits to subscribers.


https://reviews.llvm.org/D43839



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


r326272 - Inline trivial function. NFC.

2018-02-27 Thread Rafael Espindola via cfe-commits
Author: rafael
Date: Tue Feb 27 16:14:18 2018
New Revision: 326272

URL: http://llvm.org/viewvc/llvm-project?rev=326272&view=rev
Log:
Inline trivial function. NFC.

Modified:
cfe/trunk/lib/CodeGen/CGVTables.cpp

Modified: cfe/trunk/lib/CodeGen/CGVTables.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVTables.cpp?rev=326272&r1=326271&r2=326272&view=diff
==
--- cfe/trunk/lib/CodeGen/CGVTables.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVTables.cpp Tue Feb 27 16:14:18 2018
@@ -49,11 +49,6 @@ llvm::Constant *CodeGenModule::GetAddrOf
  /*DontDefer=*/true, /*IsThunk=*/true);
 }
 
-static void setThunkVisibility(CodeGenModule &CGM, const CXXMethodDecl *MD,
-   const ThunkInfo &Thunk, llvm::Function *Fn) {
-  CGM.setGVProperties(Fn, MD);
-}
-
 static void setThunkProperties(CodeGenModule &CGM, const ThunkInfo &Thunk,
llvm::Function *ThunkFn, bool ForVTable,
GlobalDecl GD) {
@@ -62,8 +57,7 @@ static void setThunkProperties(CodeGenMo
   !Thunk.Return.isEmpty());
 
   // Set the right visibility.
-  const CXXMethodDecl *MD = cast(GD.getDecl());
-  setThunkVisibility(CGM, MD, Thunk, ThunkFn);
+  CGM.setGVProperties(ThunkFn, cast(GD.getDecl()));
 
   if (CGM.supportsCOMDAT() && ThunkFn->isWeakForLinker())
 ThunkFn->setComdat(CGM.getModule().getOrInsertComdat(ThunkFn->getName()));


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


r326270 - Pass a GlobalDecl to setAliasAttributes. NFC.

2018-02-27 Thread Rafael Espindola via cfe-commits
Author: rafael
Date: Tue Feb 27 16:06:01 2018
New Revision: 326270

URL: http://llvm.org/viewvc/llvm-project?rev=326270&view=rev
Log:
Pass a GlobalDecl to setAliasAttributes. NFC.

This just makes a followup change easier to read.

Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=326270&r1=326269&r2=326270&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Tue Feb 27 16:06:01 2018
@@ -205,7 +205,7 @@ bool CodeGenModule::TryEmitDefinitionAsA
   }
 
   // Finally, set up the alias with its proper name and attributes.
-  setAliasAttributes(cast(AliasDecl.getDecl()), Alias);
+  setAliasAttributes(AliasDecl, Alias);
 
   return false;
 }

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=326270&r1=326269&r2=326270&view=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Feb 27 16:06:01 2018
@@ -1248,8 +1248,8 @@ void CodeGenModule::SetCommonAttributes(
 addUsedGlobal(GV);
 }
 
-void CodeGenModule::setAliasAttributes(const Decl *D,
-   llvm::GlobalValue *GV) {
+void CodeGenModule::setAliasAttributes(GlobalDecl GD, llvm::GlobalValue *GV) {
+  const Decl *D = GD.getDecl();
   SetCommonAttributes(D, GV);
 
   // Process the dllexport attribute based on whether the original definition
@@ -3675,7 +3675,7 @@ void CodeGenModule::EmitAliasDefinition(
 if (VD->getTLSKind())
   setTLSMode(GA, *VD);
 
-  setAliasAttributes(D, GA);
+  setAliasAttributes(GD, GA);
 }
 
 void CodeGenModule::emitIFuncDefinition(GlobalDecl GD) {

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=326270&r1=326269&r2=326270&view=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Feb 27 16:06:01 2018
@@ -1197,7 +1197,7 @@ public:
   /// attributes (i.e. it includes a call to SetCommonAttributes).
   ///
   /// NOTE: This should only be called for definitions.
-  void setAliasAttributes(const Decl *D, llvm::GlobalValue *GV);
+  void setAliasAttributes(GlobalDecl GD, llvm::GlobalValue *GV);
 
   void addReplacement(StringRef Name, llvm::Constant *C);
 

Modified: cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp?rev=326270&r1=326269&r2=326270&view=diff
==
--- cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp (original)
+++ cfe/trunk/lib/CodeGen/ItaniumCXXABI.cpp Tue Feb 27 16:06:01 2018
@@ -3637,7 +3637,7 @@ static void emitConstructorDestructorAli
   }
 
   // Finally, set up the alias with its proper name and attributes.
-  CGM.setAliasAttributes(cast(AliasDecl.getDecl()), Alias);
+  CGM.setAliasAttributes(AliasDecl, Alias);
 }
 
 void ItaniumCXXABI::emitCXXStructor(const CXXMethodDecl *MD,


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


[PATCH] D43748: [Attr] Fix paren, comma, and omitted arg printing in some cases

2018-02-27 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman closed this revision.
aaron.ballman added a comment.

Committed in r326266.


https://reviews.llvm.org/D43748



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


r326266 - Improve the way attribute argument printing happens for omitted optional arguments when pretty printing.

2018-02-27 Thread Aaron Ballman via cfe-commits
Author: aaronballman
Date: Tue Feb 27 15:49:28 2018
New Revision: 326266

URL: http://llvm.org/viewvc/llvm-project?rev=326266&view=rev
Log:
Improve the way attribute argument printing happens for omitted optional 
arguments when pretty printing.

Patch by Joel Denny.

Added:
cfe/trunk/test/Sema/attr-print.cpp
Modified:
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/test/Sema/attr-print.c
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=326266&r1=326265&r2=326266&view=diff
==
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Tue Feb 27 15:49:28 2018
@@ -1506,8 +1506,8 @@ def ObjCBridgeRelated : InheritableAttr
   let Spellings = [Clang<"objc_bridge_related">];
   let Subjects = SubjectList<[Record], ErrorDiag>;
   let Args = [IdentifierArgument<"RelatedClass">,
-  IdentifierArgument<"ClassMethod", 1>,
-  IdentifierArgument<"InstanceMethod", 1>];
+  IdentifierArgument<"ClassMethod">,
+  IdentifierArgument<"InstanceMethod">];
   let HasCustomParsing = 1;
   let Documentation = [Undocumented];
 }

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=326266&r1=326265&r2=326266&view=diff
==
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Feb 27 15:49:28 2018
@@ -1258,7 +1258,9 @@ void Parser::ParseObjCBridgeRelatedAttri
 return;
   }
 
-  // Parse optional class method name.
+  // Parse class method name.  It's non-optional in the sense that a trailing
+  // comma is required, but it can be the empty string, and then we record a
+  // nullptr.
   IdentifierLoc *ClassMethod = nullptr;
   if (Tok.is(tok::identifier)) {
 ClassMethod = ParseIdentifierLoc();
@@ -1277,7 +1279,8 @@ void Parser::ParseObjCBridgeRelatedAttri
 return;
   }
   
-  // Parse optional instance method name.
+  // Parse instance method name.  Also non-optional but empty string is
+  // permitted.
   IdentifierLoc *InstanceMethod = nullptr;
   if (Tok.is(tok::identifier))
 InstanceMethod = ParseIdentifierLoc();

Modified: cfe/trunk/test/Sema/attr-print.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-print.c?rev=326266&r1=326265&r2=326266&view=diff
==
--- cfe/trunk/test/Sema/attr-print.c (original)
+++ cfe/trunk/test/Sema/attr-print.c Tue Feb 27 15:49:28 2018
@@ -7,6 +7,9 @@ int x __attribute__((aligned(4)));
 // CHECK: int y __declspec(align(4));
 __declspec(align(4)) int y;
 
+// CHECK: short arr[3] __attribute__((aligned));
+short arr[3] __attribute__((aligned));
+
 // CHECK: void foo() __attribute__((const));
 void foo() __attribute__((const));
 

Added: cfe/trunk/test/Sema/attr-print.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-print.cpp?rev=326266&view=auto
==
--- cfe/trunk/test/Sema/attr-print.cpp (added)
+++ cfe/trunk/test/Sema/attr-print.cpp Tue Feb 27 15:49:28 2018
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 %s -ast-print | FileCheck %s
+
+// CHECK: void *as2(int, int) __attribute__((alloc_size(1, 2)));
+void *as2(int, int) __attribute__((alloc_size(1, 2)));
+// CHECK: void *as1(void *, int) __attribute__((alloc_size(2)));
+void *as1(void *, int) __attribute__((alloc_size(2)));

Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=326266&r1=326265&r2=326266&view=diff
==
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Tue Feb 27 15:49:28 2018
@@ -231,6 +231,7 @@ namespace {
 virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
 virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
 virtual void writePCHWrite(raw_ostream &OS) const = 0;
+virtual std::string getIsOmitted() const { return "false"; }
 virtual void writeValue(raw_ostream &OS) const = 0;
 virtual void writeDump(raw_ostream &OS) const = 0;
 virtual void writeDumpChildren(raw_ostream &OS) const {}
@@ -298,23 +299,28 @@ namespace {
std::string(getUpperName()) + "()");
 }
 
+std::string getIsOmitted() const override {
+  if (type == "IdentifierInfo *")
+return "!get" + getUpperName().str() + "()";
+  // FIXME: Do this declaratively in Attr.td.
+  if (getAttrName() == "AllocSize")
+return "0 == get" + getUpperName().

r326265 - Pass a GlobalDecl to setFunctionDefinitionAttributes. NFC.

2018-02-27 Thread Rafael Espindola via cfe-commits
Author: rafael
Date: Tue Feb 27 15:44:36 2018
New Revision: 326265

URL: http://llvm.org/viewvc/llvm-project?rev=326265&view=rev
Log:
Pass a GlobalDecl to setFunctionDefinitionAttributes. NFC.

This just makes a followup patch easier to read.

Modified:
cfe/trunk/lib/CodeGen/CGCXX.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=326265&r1=326264&r2=326265&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Tue Feb 27 15:44:36 2018
@@ -230,7 +230,7 @@ llvm::Function *CodeGenModule::codegenCX
   setFunctionDLLStorageClass(GD, Fn);
 
   CodeGenFunction(*this).GenerateCode(GD, Fn, FnInfo);
-  setFunctionDefinitionAttributes(MD, Fn);
+  setFunctionDefinitionAttributes(GD, Fn);
   SetLLVMFunctionAttributesForDefinition(MD, Fn);
   return Fn;
 }

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=326265&r1=326264&r2=326265&view=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Feb 27 15:44:36 2018
@@ -1080,9 +1080,9 @@ llvm::ConstantInt *CodeGenModule::Create
   return llvm::ConstantInt::get(Int64Ty, llvm::MD5Hash(MDS->getString()));
 }
 
-void CodeGenModule::setFunctionDefinitionAttributes(const FunctionDecl *D,
+void CodeGenModule::setFunctionDefinitionAttributes(GlobalDecl GD,
 llvm::Function *F) {
-  setNonAliasAttributes(D, F);
+  setNonAliasAttributes(GD.getDecl(), F);
 }
 
 void CodeGenModule::SetLLVMFunctionAttributes(const Decl *D,
@@ -3591,7 +3591,7 @@ void CodeGenModule::EmitGlobalFunctionDe
 
   CodeGenFunction(*this).GenerateCode(D, Fn, FI);
 
-  setFunctionDefinitionAttributes(D, Fn);
+  setFunctionDefinitionAttributes(GD, Fn);
   SetLLVMFunctionAttributesForDefinition(D, Fn);
 
   if (const ConstructorAttr *CA = D->getAttr())

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=326265&r1=326264&r2=326265&view=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Feb 27 15:44:36 2018
@@ -1183,8 +1183,7 @@ public:
   bool TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D);
 
   /// Set attributes for a global definition.
-  void setFunctionDefinitionAttributes(const FunctionDecl *D,
-   llvm::Function *F);
+  void setFunctionDefinitionAttributes(GlobalDecl GD, llvm::Function *F);
 
   llvm::GlobalValue *GetGlobalValue(StringRef Ref);
 


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


[PATCH] D43815: CodeGen tests - typo fixes

2018-02-27 Thread Craig Topper via Phabricator via cfe-commits
craig.topper accepted this revision.
craig.topper added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rC Clang

https://reviews.llvm.org/D43815



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


[PATCH] D43814: [x86][CET] Introduce _get_ssp, _inc_ssp intrinsics

2018-02-27 Thread Craig Topper via Phabricator via cfe-commits
craig.topper added inline comments.



Comment at: lib/Headers/cetintrin.h:44
+
+static __inline__ void __DEFAULT_FN_ATTRS _inc_ssp(unsigned int __a) {
+  __builtin_ia32_incsspq(__a);

Start a new #ifdef __x86_64__ here that is just for your new intrinsics. That 
way it doesn't look weird that the #else contains fewer functions than the #if.



Comment at: lib/Headers/cetintrin.h:45
+static __inline__ void __DEFAULT_FN_ATTRS _inc_ssp(unsigned int __a) {
+  __builtin_ia32_incsspq(__a);
+}

Where is the zeroing behavior for older CPUs coming from? This implementation 
looks identical to _incsspq?



Comment at: lib/Headers/cetintrin.h:65
+
+static __inline__ unsigned long long __DEFAULT_FN_ATTRS _get_ssp(void) {
+  return __builtin_ia32_rdsspq(0);

same comments as above.


Repository:
  rC Clang

https://reviews.llvm.org/D43814



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


[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-02-27 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb updated this revision to Diff 136164.
bsdjhb added a comment.
Herald added a subscriber: christof.

- Rebase after N32 commit.
- Use ldc1/sdc1 rather than l.d and s.d.


Repository:
  rUNW libunwind

https://reviews.llvm.org/D41968

Files:
  include/__libunwind_config.h
  include/libunwind.h
  src/Registers.hpp
  src/UnwindRegistersRestore.S
  src/UnwindRegistersSave.S
  src/libunwind.cpp

Index: src/libunwind.cpp
===
--- src/libunwind.cpp
+++ src/libunwind.cpp
@@ -61,10 +61,9 @@
 # define REGISTER_KIND Registers_arm
 #elif defined(__or1k__)
 # define REGISTER_KIND Registers_or1k
-#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
-defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
 # define REGISTER_KIND Registers_mips_o32
-#elif defined(__mips64) && defined(__mips_soft_float)
+#elif defined(__mips64)
 # define REGISTER_KIND Registers_mips_newabi
 #elif defined(__mips__)
 # warning The MIPS architecture is not supported with this ABI and environment!
Index: src/UnwindRegistersSave.S
===
--- src/UnwindRegistersSave.S
+++ src/UnwindRegistersSave.S
@@ -116,8 +116,7 @@
   xorl  %eax, %eax# return UNW_ESUCCESS
   ret
 
-#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
-defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
@@ -168,12 +167,65 @@
   sw$8,  (4 * 33)($4)
   mflo  $8
   sw$8,  (4 * 34)($4)
+#ifdef __mips_hard_float
+#if __mips_fpr == 32
+  sdc1  $f0, (4 * 36 + 8 * 0)($4)
+  sdc1  $f2, (4 * 36 + 8 * 2)($4)
+  sdc1  $f4, (4 * 36 + 8 * 4)($4)
+  sdc1  $f6, (4 * 36 + 8 * 6)($4)
+  sdc1  $f8, (4 * 36 + 8 * 8)($4)
+  sdc1  $f10, (4 * 36 + 8 * 10)($4)
+  sdc1  $f12, (4 * 36 + 8 * 12)($4)
+  sdc1  $f14, (4 * 36 + 8 * 14)($4)
+  sdc1  $f16, (4 * 36 + 8 * 16)($4)
+  sdc1  $f18, (4 * 36 + 8 * 18)($4)
+  sdc1  $f20, (4 * 36 + 8 * 20)($4)
+  sdc1  $f22, (4 * 36 + 8 * 22)($4)
+  sdc1  $f24, (4 * 36 + 8 * 24)($4)
+  sdc1  $f26, (4 * 36 + 8 * 26)($4)
+  sdc1  $f28, (4 * 36 + 8 * 28)($4)
+  sdc1  $f30, (4 * 36 + 8 * 30)($4)
+#else
+  sdc1  $f0, (4 * 36 + 8 * 0)($4)
+  sdc1  $f1, (4 * 36 + 8 * 1)($4)
+  sdc1  $f2, (4 * 36 + 8 * 2)($4)
+  sdc1  $f3, (4 * 36 + 8 * 3)($4)
+  sdc1  $f4, (4 * 36 + 8 * 4)($4)
+  sdc1  $f5, (4 * 36 + 8 * 5)($4)
+  sdc1  $f6, (4 * 36 + 8 * 6)($4)
+  sdc1  $f7, (4 * 36 + 8 * 7)($4)
+  sdc1  $f8, (4 * 36 + 8 * 8)($4)
+  sdc1  $f9, (4 * 36 + 8 * 9)($4)
+  sdc1  $f10, (4 * 36 + 8 * 10)($4)
+  sdc1  $f11, (4 * 36 + 8 * 11)($4)
+  sdc1  $f12, (4 * 36 + 8 * 12)($4)
+  sdc1  $f13, (4 * 36 + 8 * 13)($4)
+  sdc1  $f14, (4 * 36 + 8 * 14)($4)
+  sdc1  $f15, (4 * 36 + 8 * 15)($4)
+  sdc1  $f16, (4 * 36 + 8 * 16)($4)
+  sdc1  $f17, (4 * 36 + 8 * 17)($4)
+  sdc1  $f18, (4 * 36 + 8 * 18)($4)
+  sdc1  $f19, (4 * 36 + 8 * 19)($4)
+  sdc1  $f20, (4 * 36 + 8 * 20)($4)
+  sdc1  $f21, (4 * 36 + 8 * 21)($4)
+  sdc1  $f22, (4 * 36 + 8 * 22)($4)
+  sdc1  $f23, (4 * 36 + 8 * 23)($4)
+  sdc1  $f24, (4 * 36 + 8 * 24)($4)
+  sdc1  $f25, (4 * 36 + 8 * 25)($4)
+  sdc1  $f26, (4 * 36 + 8 * 26)($4)
+  sdc1  $f27, (4 * 36 + 8 * 27)($4)
+  sdc1  $f28, (4 * 36 + 8 * 28)($4)
+  sdc1  $f29, (4 * 36 + 8 * 29)($4)
+  sdc1  $f30, (4 * 36 + 8 * 30)($4)
+  sdc1  $f31, (4 * 36 + 8 * 31)($4)
+#endif
+#endif
   jr	$31
   # return UNW_ESUCCESS
   or$2, $0, $0
   .set pop
 
-#elif defined(__mips64) && defined(__mips_soft_float)
+#elif defined(__mips64)
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
@@ -224,6 +276,40 @@
   sd$8,  (8 * 33)($4)
   mflo  $8
   sd$8,  (8 * 34)($4)
+#ifdef __mips_hard_float
+  sdc1  $f0, (8 * 35)($4)
+  sdc1  $f1, (8 * 36)($4)
+  sdc1  $f2, (8 * 37)($4)
+  sdc1  $f3, (8 * 38)($4)
+  sdc1  $f4, (8 * 39)($4)
+  sdc1  $f5, (8 * 40)($4)
+  sdc1  $f6, (8 * 41)($4)
+  sdc1  $f7, (8 * 42)($4)
+  sdc1  $f8, (8 * 43)($4)
+  sdc1  $f9, (8 * 44)($4)
+  sdc1  $f10, (8 * 45)($4)
+  sdc1  $f11, (8 * 46)($4)
+  sdc1  $f12, (8 * 47)($4)
+  sdc1  $f13, (8 * 48)($4)
+  sdc1  $f14, (8 * 49)($4)
+  sdc1  $f15, (8 * 50)($4)
+  sdc1  $f16, (8 * 51)($4)
+  sdc1  $f17, (8 * 52)($4)
+  sdc1  $f18, (8 * 53)($4)
+  sdc1  $f19, (8 * 54)($4)
+  sdc1  $f20, (8 * 55)($4)
+  sdc1  $f21, (8 * 56)($4)
+  sdc1  $f22, (8 * 57)($4)
+  sdc1  $f23, (8 * 58)($4)
+  sdc1  $f24, (8 * 59)($4)
+  sdc1  $f25, (8 * 60)($4)
+  sdc1  $f26, (8 * 61)($4)
+  sdc1  $f27, (8 * 62)($4)
+  sdc1  $f28, (8 * 63)($4)
+  sdc1  $f29, (8 * 64)($4)
+  sdc1  $f30, (8 * 65)($4)
+  sdc1  $f31, (8 * 66)($4)
+#endif
   jr	$31
   # return UNW_ESUCCESS
   or$2, $0, $0
Index: src/UnwindRegistersRestore.S
===
--- src/UnwindRegistersRestore.S
+++ src/UnwindRegistersRestore.S
@@ -799,8 +799,7 @@
   l.jr r9
l.nop
 
-#elif

[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-02-27 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb added a comment.

Hmmm, so I was somewhat mistaken as DwarfInstructions.hpp::stepWithDwarf() does 
use the Register class's setFloatRegister(), however, it assumes that the 
floating point register is always a double 
(DwarfInstructions.hpp::getSavedFloatRegister() uses AddressSpace::getDouble() 
to read a double from memory).  So I think that means that the NEWABI cases 
work as-is.  O32 with 64-bit FP registers should also work as-is.  However, O32 
with 32-bit FP registers will not quite work.  The DWARF info for O32 with 
32-bit registers does save/restore individual 32-bit registers:

  06dc 0034 06e0 FDE cie= pc=d384..d46c
DW_CFA_advance_loc4: 16 to d394
DW_CFA_def_cfa_offset: 56
DW_CFA_advance_loc4: 20 to d3a8
DW_CFA_offset: r31 at cfa-12
DW_CFA_offset: r17 at cfa-16
DW_CFA_offset: r16 at cfa-20
DW_CFA_offset: r52 at cfa-4
DW_CFA_offset: r53 at cfa-8
  ...

If the compiler happens to always save and restore them in pairs then the 
current approach will work.  If we don't want to assume that they are saved and 
restored in pairs, then we could instead perhaps claim that 32-bit FP registers 
aren't really floating point but are just plain 32-bit registers.  This would 
make unwinding work (I believe), but would mean that one would need to use 
unw_get_reg() instead of unw_get_fpreg() to fetch individual 32-bit FP 
registers.


https://reviews.llvm.org/D41968



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


[PATCH] D41102: Setup clang-doc frontend framework

2018-02-27 Thread Julie Hockett via Phabricator via cfe-commits
juliehockett added a comment.

In https://reviews.llvm.org/D41102#1020808, @lebedev.ri wrote:

> Ok, great.
>  And it will also complain if you try to output a block within block?


Um...no. Since you can have subblocks within blocks.




Comment at: clang-doc/BitcodeWriter.cpp:191
+  Record.clear();
+  for (const char C : BlockIdNameMap[ID]) Record.push_back(C);
+  Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, Record);

lebedev.ri wrote:
> juliehockett wrote:
> > lebedev.ri wrote:
> > > Why do we have this indirection?
> > > Is there a need to first to (unefficiently?) copy to `Record`, and then 
> > > emit from there?
> > > Wouldn't this work just as well?
> > > ```
> > > Record.clear();
> > > Stream.EmitRecord(llvm::bitc::BLOCKINFO_CODE_BLOCKNAME, 
> > > BlockIdNameMap[ID]);
> > > ```
> > No, since `BlockIdNameMap[ID]` returns a `StringRef`, which can be 
> > manipulated into an `std::string` or a `const char*`, but the `Stream` 
> > wants an `unsigned char`. So, the copying is to satisfy that. Unless 
> > there's a better way to convert a `StringRef` into an array of `unsigned 
> > char`?
> Aha, i see, did not think of that.
> But there is a `bytes()` function in `StringRef`, which returns 
> `iterator_range`. 
> Would it help? 
> http://llvm.org/doxygen/classllvm_1_1StringRef.html#a5e8f22c3553e341404b445430a3b075b
Replaced it with an ArrayRef to the `bytes_begin()` and `bytes_end()`, but that 
only works for the block id, not the record id, since `emitRecordId()` also has 
to emit the ID number in addition to the name in the same record.



Comment at: clang-doc/BitcodeWriter.cpp:265
+  if (!prepRecordData(ID, !OmitFilenames)) return;
+  // FIXME: Assert that the line number is of the appropriate size.
+  Record.push_back(Loc.LineNumber);

lebedev.ri wrote:
> I think it is as simple as
> ```
> assert(Loc.LineNumber < (1U << BitCodeConstants::LineNumberSize));
> ```
> ?
`LineNumber` is  a signed int, so the compiler complains that we're comparing 
signed and unsigned ints.


https://reviews.llvm.org/D41102



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


[PATCH] D41102: Setup clang-doc frontend framework

2018-02-27 Thread Julie Hockett via Phabricator via cfe-commits
juliehockett updated this revision to Diff 136161.
juliehockett marked 15 inline comments as done.
juliehockett added a comment.

Fixing comments


https://reviews.llvm.org/D41102

Files:
  CMakeLists.txt
  clang-doc/BitcodeWriter.cpp
  clang-doc/BitcodeWriter.h
  clang-doc/CMakeLists.txt
  clang-doc/ClangDoc.h
  clang-doc/Mapper.cpp
  clang-doc/Mapper.h
  clang-doc/Representation.h
  clang-doc/Serialize.cpp
  clang-doc/Serialize.h
  clang-doc/tool/CMakeLists.txt
  clang-doc/tool/ClangDocMain.cpp
  docs/clang-doc.rst
  test/CMakeLists.txt
  test/clang-doc/mapper-class-in-class.cpp
  test/clang-doc/mapper-class-in-function.cpp
  test/clang-doc/mapper-class.cpp
  test/clang-doc/mapper-enum.cpp
  test/clang-doc/mapper-function.cpp
  test/clang-doc/mapper-method.cpp
  test/clang-doc/mapper-namespace.cpp
  test/clang-doc/mapper-struct.cpp
  test/clang-doc/mapper-union.cpp

Index: test/clang-doc/mapper-union.cpp
===
--- /dev/null
+++ test/clang-doc/mapper-union.cpp
@@ -0,0 +1,28 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc --dump --omit-filenames -doxygen -p %t %t/test.cpp -output=%t/docs
+// RUN: llvm-bcanalyzer %t/docs/c:@u...@d.bc --dump | FileCheck %s
+
+union D { int X; int Y; };
+// CHECK: 
+// CHECK: 
+  // CHECK: 
+// CHECK: 
+// CHECK: 
+  // CHECK:  blob data = 'c:@U@D'
+  // CHECK:  blob data = 'D'
+  // CHECK: 
+  // CHECK: 
+  // CHECK: 
+// CHECK:  blob data = 'int'
+// CHECK:  blob data = 'D::X'
+// CHECK: 
+  // CHECK: 
+  // CHECK: 
+// CHECK:  blob data = 'int'
+// CHECK:  blob data = 'D::Y'
+// CHECK: 
+  // CHECK: 
+// CHECK: 
Index: test/clang-doc/mapper-struct.cpp
===
--- /dev/null
+++ test/clang-doc/mapper-struct.cpp
@@ -0,0 +1,22 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc --dump --omit-filenames -doxygen -p %t %t/test.cpp -output=%t/docs
+// RUN: llvm-bcanalyzer %t/docs/c:@s...@c.bc --dump | FileCheck %s
+
+struct C { int i; };
+// CHECK: 
+// CHECK: 
+  // CHECK: 
+// CHECK: 
+// CHECK: 
+  // CHECK:  blob data = 'c:@S@C'
+  // CHECK:  blob data = 'C'
+  // CHECK: 
+  // CHECK: 
+// CHECK:  blob data = 'int'
+// CHECK:  blob data = 'C::i'
+// CHECK: 
+  // CHECK: 
+// CHECK: 
Index: test/clang-doc/mapper-namespace.cpp
===
--- /dev/null
+++ test/clang-doc/mapper-namespace.cpp
@@ -0,0 +1,17 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc --dump --omit-filenames -doxygen -p %t %t/test.cpp -output=%t/docs
+// RUN: llvm-bcanalyzer %t/docs/c:@n...@a.bc --dump | FileCheck %s
+
+namespace A {}
+// CHECK: 
+// CHECK: 
+  // CHECK: 
+// CHECK: 
+// CHECK: 
+  // CHECK:  blob data = 'c:@N@A'
+  // CHECK:  blob data = 'A'
+// CHECK: 
+
Index: test/clang-doc/mapper-method.cpp
===
--- /dev/null
+++ test/clang-doc/mapper-method.cpp
@@ -0,0 +1,31 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc --dump --omit-filenames -doxygen -p %t %t/test.cpp -output=%t/docs
+// RUN: llvm-bcanalyzer %t/docs/c:@S@G@F@Method#I#.bc --dump | FileCheck %s
+
+class G {
+public: 
+	int Method(int param) { return param; }
+};
+// CHECK: 
+// CHECK: 
+  // CHECK: 
+// CHECK: 
+// CHECK: 
+  // CHECK:  blob data = 'c:@S@G@F@Method#I#'
+  // CHECK:  blob data = 'Method'
+  // CHECK:  blob data = 'c:@S@G'
+  // CHECK: 
+  // CHECK: 
+  // CHECK:  blob data = 'c:@S@G'
+  // CHECK: 
+// CHECK:  blob data = 'int'
+  // CHECK: 
+  // CHECK: 
+// CHECK:  blob data = 'int'
+// CHECK:  blob data = 'param'
+  // CHECK: 
+// CHECK: 
+
Index: test/clang-doc/mapper-function.cpp
===
--- /dev/null
+++ test/clang-doc/mapper-function.cpp
@@ -0,0 +1,25 @@
+// RUN: rm -rf %t
+// RUN: mkdir %t
+// RUN: echo "" > %t/compile_flags.txt
+// RUN: cp "%s" "%t/test.cpp"
+// RUN: clang-doc --dump --omit-filenames -doxygen -p %t %t/test.cpp -output=%t/docs
+// RUN: llvm-bcanalyzer %t/docs/c:@F@F#I#.bc --dump | FileCheck %s
+
+int F(int param) { return param; }
+// CHECK: 
+// CHECK: 
+  // CHECK: 
+// CHECK: 
+// CHECK: 
+  // CHECK:  blob data = 'c:@F@F#I#'
+  // CHECK:  blob data = 'F'
+  // CHECK: 
+  // CHECK: 
+// CHECK:  blob data = 'int'
+  // CHECK: 
+  // CHECK: 
+// CHECK:  blob data = 'int'
+// CHECK:  blob data = 'param'
+  // CHECK: 
+// CHECK: 
+
Index: test/clang-doc/mapper-enum.cpp
===
--- /dev/null
+++ test/clang-doc/mapper-enum.cpp
@@ -0,0 +1,24 @@
+// RUN: rm -rf %t
+// RUN

[PATCH] D43748: [Attr] Fix paren, comma, and omitted arg printing in some cases

2018-02-27 Thread Joel E. Denny via Phabricator via cfe-commits
jdenny added a comment.

In https://reviews.llvm.org/D43748#1021246, @aaron.ballman wrote:

> LGTM! I can commit on your behalf, or, if you plan to continue submitting 
> patches, you can ask for commit privileges 
> (http://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access) and 
> commit yourself. Either way works for me.


I'll definitely pursue commit privileges.  If you don't mind committing 
anything you accept today, that would be great.  Thanks for your help!


https://reviews.llvm.org/D43748



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


[PATCH] D43748: [Attr] Fix paren, comma, and omitted arg printing in some cases

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

LGTM! I can commit on your behalf, or, if you plan to continue submitting 
patches, you can ask for commit privileges 
(http://llvm.org/docs/DeveloperPolicy.html#obtaining-commit-access) and commit 
yourself. Either way works for me.


https://reviews.llvm.org/D43748



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


[PATCH] D43747: [Attr] Fix pointer_with_type_tag assert fail for variadic

2018-02-27 Thread Joel E. Denny via Phabricator via cfe-commits
jdenny added a comment.

In https://reviews.llvm.org/D43747#1021234, @aaron.ballman wrote:

> In https://reviews.llvm.org/D43747#1021209, @jdenny wrote:
>
> > In https://reviews.llvm.org/D43747#1018844, @aaron.ballman wrote:
> >
> > > Committed in r326057.
> > >
> > > If you're not already on IRC, I would recommend joining the #llvm channel 
> > > on OFTC so that you can watch for build break notifications from the 
> > > build bots.
> >
> >
> > Thanks.  Can your recommend effective ways to make use of this?  Do 
> > developers just stay logged in all day to catch failures relevant to their 
> > work?
>
>
> Generally, yes. Some folks will even go so far as to set up IRC bouncers to 
> capture messages while their host machine is asleep and no longer connected 
> (but this is by no means required). The key thing is: most build bots send 
> out an email if a commit breaks the build, but not all bots do (some only 
> send to IRC) and that email goes to whoever is on the commit list. So if you 
> make commits or have someone commit something on your behalf, being in the 
> IRC channel can help you quickly fix issues. However, if you're not on the 
> IRC channel, someone else will help make sure you get notified if something 
> goes wrong, so being in IRC isn't required.


Makes sense.  Thanks for the tips.


https://reviews.llvm.org/D43747



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


[PATCH] D43798: [analyzer] UndefinedAssignment: Fix warning message on implicit copy/move constructors.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326258: [analyzer] UndefinedAssignmentChecker: Better 
warning message in implicit ctors. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43798?vs=136151&id=136154#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43798

Files:
  cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
  cfe/trunk/test/Analysis/implicit-ctor-undef-value.cpp

Index: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -51,17 +51,20 @@
   if (!N)
 return;
 
-  const char *str = "Assigned value is garbage or undefined";
-
+  static const char *const DefaultMsg =
+  "Assigned value is garbage or undefined";
   if (!BT)
-BT.reset(new BuiltinBug(this, str));
+BT.reset(new BuiltinBug(this, DefaultMsg));
 
   // Generate a report for this bug.
+  llvm::SmallString<128> Str;
+  llvm::raw_svector_ostream OS(Str);
+
   const Expr *ex = nullptr;
 
   while (StoreE) {
 if (const UnaryOperator *U = dyn_cast(StoreE)) {
-  str = "The expression is an uninitialized value. "
+  OS << "The expression is an uninitialized value. "
 "The computed value will also be garbage";
 
   ex = U->getSubExpr();
@@ -71,7 +74,7 @@
 if (const BinaryOperator *B = dyn_cast(StoreE)) {
   if (B->isCompoundAssignmentOp()) {
 if (C.getSVal(B->getLHS()).isUndef()) {
-  str = "The left expression of the compound assignment is an "
+  OS << "The left expression of the compound assignment is an "
 "uninitialized value. The computed value will also be garbage";
   ex = B->getLHS();
   break;
@@ -87,10 +90,26 @@
   ex = VD->getInit();
 }
 
+if (const auto *CD =
+dyn_cast(C.getStackFrame()->getDecl())) {
+  if (CD->isImplicit()) {
+for (auto I : CD->inits()) {
+  if (I->getInit()->IgnoreImpCasts() == StoreE) {
+OS << "Value assigned to field '" << I->getMember()->getName()
+   << "' in implicit constructor is garbage or undefined";
+break;
+  }
+}
+  }
+}
+
 break;
   }
 
-  auto R = llvm::make_unique(*BT, str, N);
+  if (OS.str().empty())
+OS << DefaultMsg;
+
+  auto R = llvm::make_unique(*BT, OS.str(), N);
   if (ex) {
 R->addRange(ex->getSourceRange());
 bugreporter::trackNullOrUndefValue(N, ex, *R);
Index: cfe/trunk/test/Analysis/implicit-ctor-undef-value.cpp
===
--- cfe/trunk/test/Analysis/implicit-ctor-undef-value.cpp
+++ cfe/trunk/test/Analysis/implicit-ctor-undef-value.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+
+namespace implicit_constructor {
+struct S {
+public:
+  S() {}
+  S(const S &) {}
+};
+
+// Warning is in a weird position because the body of the constructor is
+// missing. Specify which field is being assigned.
+class C { // expected-warning{{Value assigned to field 'y' in implicit constructor is garbage or undefined}}
+  // expected-note@-1{{Value assigned to field 'y' in implicit constructor is garbage or undefined}}
+  int x, y;
+  S s;
+
+public:
+  C(): x(0) {}
+};
+
+void test() {
+  C c1;
+  C c2(c1); // expected-note{{Calling implicit copy constructor for 'C'}}
+}
+} // end namespace implicit_constructor
+
+
+namespace explicit_constructor {
+class C {
+  int x, y;
+
+public:
+  C(): x(0) {}
+  // It is not necessary to specify which field is being assigned to.
+  C(const C &c):
+x(c.x),
+y(c.y) // expected-warning{{Assigned value is garbage or undefined}}
+   // expected-note@-1{{Assigned value is garbage or undefined}}
+  {}
+};
+
+void test() {
+  C c1;
+  C c2(c1); // expected-note{{Calling copy constructor for 'C'}}
+}
+} // end namespace explicit_constructor
+
+
+namespace base_class_constructor {
+struct S {
+public:
+  S() {}
+  S(const S &) {}
+};
+
+class C { // expected-warning{{Value assigned to field 'y' in implicit constructor is garbage or undefined}}
+  // expected-note@-1{{Value assigned to field 'y' in implicit constructor is garbage or undefined}}
+  int x, y;
+  S s;
+
+public:
+  C(): x(0) {}
+};
+
+class D: public C {
+public:
+  D(): C() {}
+};
+
+void test() {
+  D d1;
+  D d2(d1); // expected-note   {{Calling implicit copy constructor for 'D'}}
+// expected-note@-1{{Calling implicit copy constructor for 'C'}}
+}
+} // end namespace base_class_constructor
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-co

r326258 - [analyzer] UndefinedAssignmentChecker: Better warning message in implicit ctors.

2018-02-27 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Tue Feb 27 14:05:55 2018
New Revision: 326258

URL: http://llvm.org/viewvc/llvm-project?rev=326258&view=rev
Log:
[analyzer] UndefinedAssignmentChecker: Better warning message in implicit ctors.

When a class forgets to initialize a field in the constructor, and then gets
copied around, a warning is emitted that the value assigned to a specific field
is undefined.

When the copy/move constructor is implicit (not written out in the code) but not
trivial (is not a trivial memory copy, eg. because members have an explicit copy
constructor), the body of such constructor is auto-generated in the AST.
In this case the checker's warning message is squeezed at the top of
the class declaration, and it gets hard to guess which field is at fault.

Fix the warning message to include the name of the field.

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

Added:
cfe/trunk/test/Analysis/implicit-ctor-undef-value.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp?rev=326258&r1=326257&r2=326258&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp Tue 
Feb 27 14:05:55 2018
@@ -51,17 +51,20 @@ void UndefinedAssignmentChecker::checkBi
   if (!N)
 return;
 
-  const char *str = "Assigned value is garbage or undefined";
-
+  static const char *const DefaultMsg =
+  "Assigned value is garbage or undefined";
   if (!BT)
-BT.reset(new BuiltinBug(this, str));
+BT.reset(new BuiltinBug(this, DefaultMsg));
 
   // Generate a report for this bug.
+  llvm::SmallString<128> Str;
+  llvm::raw_svector_ostream OS(Str);
+
   const Expr *ex = nullptr;
 
   while (StoreE) {
 if (const UnaryOperator *U = dyn_cast(StoreE)) {
-  str = "The expression is an uninitialized value. "
+  OS << "The expression is an uninitialized value. "
 "The computed value will also be garbage";
 
   ex = U->getSubExpr();
@@ -71,7 +74,7 @@ void UndefinedAssignmentChecker::checkBi
 if (const BinaryOperator *B = dyn_cast(StoreE)) {
   if (B->isCompoundAssignmentOp()) {
 if (C.getSVal(B->getLHS()).isUndef()) {
-  str = "The left expression of the compound assignment is an "
+  OS << "The left expression of the compound assignment is an "
 "uninitialized value. The computed value will also be garbage";
   ex = B->getLHS();
   break;
@@ -87,10 +90,26 @@ void UndefinedAssignmentChecker::checkBi
   ex = VD->getInit();
 }
 
+if (const auto *CD =
+dyn_cast(C.getStackFrame()->getDecl())) {
+  if (CD->isImplicit()) {
+for (auto I : CD->inits()) {
+  if (I->getInit()->IgnoreImpCasts() == StoreE) {
+OS << "Value assigned to field '" << I->getMember()->getName()
+   << "' in implicit constructor is garbage or undefined";
+break;
+  }
+}
+  }
+}
+
 break;
   }
 
-  auto R = llvm::make_unique(*BT, str, N);
+  if (OS.str().empty())
+OS << DefaultMsg;
+
+  auto R = llvm::make_unique(*BT, OS.str(), N);
   if (ex) {
 R->addRange(ex->getSourceRange());
 bugreporter::trackNullOrUndefValue(N, ex, *R);

Added: cfe/trunk/test/Analysis/implicit-ctor-undef-value.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/implicit-ctor-undef-value.cpp?rev=326258&view=auto
==
--- cfe/trunk/test/Analysis/implicit-ctor-undef-value.cpp (added)
+++ cfe/trunk/test/Analysis/implicit-ctor-undef-value.cpp Tue Feb 27 14:05:55 
2018
@@ -0,0 +1,75 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text 
-verify %s
+
+namespace implicit_constructor {
+struct S {
+public:
+  S() {}
+  S(const S &) {}
+};
+
+// Warning is in a weird position because the body of the constructor is
+// missing. Specify which field is being assigned.
+class C { // expected-warning{{Value assigned to field 'y' in implicit 
constructor is garbage or undefined}}
+  // expected-note@-1{{Value assigned to field 'y' in implicit 
constructor is garbage or undefined}}
+  int x, y;
+  S s;
+
+public:
+  C(): x(0) {}
+};
+
+void test() {
+  C c1;
+  C c2(c1); // expected-note{{Calling implicit copy constructor for 'C'}}
+}
+} // end namespace implicit_constructor
+
+
+namespace explicit_constructor {
+class C {
+  int x, y;
+
+public:
+  C(): x(0) {}
+  // It is not necessary to specify which field is being assigned to.
+  C(const C &c):
+x(c.x),
+y(c.y) // expected-warning{{Assigned value is garbage or undefined}}
+   // expected-note@-1{{

[PATCH] D43747: [Attr] Fix pointer_with_type_tag assert fail for variadic

2018-02-27 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added a comment.

In https://reviews.llvm.org/D43747#1021209, @jdenny wrote:

> In https://reviews.llvm.org/D43747#1018844, @aaron.ballman wrote:
>
> > Committed in r326057.
> >
> > If you're not already on IRC, I would recommend joining the #llvm channel 
> > on OFTC so that you can watch for build break notifications from the build 
> > bots.
>
>
> Thanks.  Can your recommend effective ways to make use of this?  Do 
> developers just stay logged in all day to catch failures relevant to their 
> work?


Generally, yes. Some folks will even go so far as to set up IRC bouncers to 
capture messages while their host machine is asleep and no longer connected 
(but this is by no means required). The key thing is: most build bots send out 
an email if a commit breaks the build, but not all bots do (some only send to 
IRC) and that email goes to whoever is on the commit list. So if you make 
commits or have someone commit something on your behalf, being in the IRC 
channel can help you quickly fix issues. However, if you're not on the IRC 
channel, someone else will help make sure you get notified if something goes 
wrong, so being in IRC isn't required.


https://reviews.llvm.org/D43747



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


[PATCH] D43798: [analyzer] UndefinedAssignment: Fix warning message on implicit copy/move constructors.

2018-02-27 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 136151.
NoQ marked an inline comment as done.
NoQ added a comment.

Mention the implicit constructor in the warning message.


https://reviews.llvm.org/D43798

Files:
  lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
  test/Analysis/implicit-ctor-undef-value.cpp

Index: test/Analysis/implicit-ctor-undef-value.cpp
===
--- /dev/null
+++ test/Analysis/implicit-ctor-undef-value.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+
+namespace implicit_constructor {
+struct S {
+public:
+  S() {}
+  S(const S &) {}
+};
+
+// Warning is in a weird position because the body of the constructor is
+// missing. Specify which field is being assigned.
+class C { // expected-warning{{Value assigned to field 'y' in implicit constructor is garbage or undefined}}
+  // expected-note@-1{{Value assigned to field 'y' in implicit constructor is garbage or undefined}}
+  int x, y;
+  S s;
+
+public:
+  C(): x(0) {}
+};
+
+void test() {
+  C c1;
+  C c2(c1); // expected-note{{Calling implicit copy constructor for 'C'}}
+}
+} // end namespace implicit_constructor
+
+
+namespace explicit_constructor {
+class C {
+  int x, y;
+
+public:
+  C(): x(0) {}
+  // It is not necessary to specify which field is being assigned to.
+  C(const C &c):
+x(c.x),
+y(c.y) // expected-warning{{Assigned value is garbage or undefined}}
+   // expected-note@-1{{Assigned value is garbage or undefined}}
+  {}
+};
+
+void test() {
+  C c1;
+  C c2(c1); // expected-note{{Calling copy constructor for 'C'}}
+}
+} // end namespace explicit_constructor
+
+
+namespace base_class_constructor {
+struct S {
+public:
+  S() {}
+  S(const S &) {}
+};
+
+class C { // expected-warning{{Value assigned to field 'y' in implicit constructor is garbage or undefined}}
+  // expected-note@-1{{Value assigned to field 'y' in implicit constructor is garbage or undefined}}
+  int x, y;
+  S s;
+
+public:
+  C(): x(0) {}
+};
+
+class D: public C {
+public:
+  D(): C() {}
+};
+
+void test() {
+  D d1;
+  D d2(d1); // expected-note   {{Calling implicit copy constructor for 'D'}}
+// expected-note@-1{{Calling implicit copy constructor for 'C'}}
+}
+} // end namespace base_class_constructor
Index: lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -51,17 +51,20 @@
   if (!N)
 return;
 
-  const char *str = "Assigned value is garbage or undefined";
-
+  static const char *const DefaultMsg =
+  "Assigned value is garbage or undefined";
   if (!BT)
-BT.reset(new BuiltinBug(this, str));
+BT.reset(new BuiltinBug(this, DefaultMsg));
 
   // Generate a report for this bug.
+  llvm::SmallString<128> Str;
+  llvm::raw_svector_ostream OS(Str);
+
   const Expr *ex = nullptr;
 
   while (StoreE) {
 if (const UnaryOperator *U = dyn_cast(StoreE)) {
-  str = "The expression is an uninitialized value. "
+  OS << "The expression is an uninitialized value. "
 "The computed value will also be garbage";
 
   ex = U->getSubExpr();
@@ -71,7 +74,7 @@
 if (const BinaryOperator *B = dyn_cast(StoreE)) {
   if (B->isCompoundAssignmentOp()) {
 if (C.getSVal(B->getLHS()).isUndef()) {
-  str = "The left expression of the compound assignment is an "
+  OS << "The left expression of the compound assignment is an "
 "uninitialized value. The computed value will also be garbage";
   ex = B->getLHS();
   break;
@@ -87,10 +90,26 @@
   ex = VD->getInit();
 }
 
+if (const auto *CD =
+dyn_cast(C.getStackFrame()->getDecl())) {
+  if (CD->isImplicit()) {
+for (auto I : CD->inits()) {
+  if (I->getInit()->IgnoreImpCasts() == StoreE) {
+OS << "Value assigned to field '" << I->getMember()->getName()
+   << "' in implicit constructor is garbage or undefined";
+break;
+  }
+}
+  }
+}
+
 break;
   }
 
-  auto R = llvm::make_unique(*BT, str, N);
+  if (OS.str().empty())
+OS << DefaultMsg;
+
+  auto R = llvm::make_unique(*BT, OS.str(), N);
   if (ex) {
 R->addRange(ex->getSourceRange());
 bugreporter::trackNullOrUndefValue(N, ex, *R);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43798: [analyzer] UndefinedAssignment: Fix warning message on implicit copy/move constructors.

2018-02-27 Thread Devin Coughlin via Phabricator via cfe-commits
dcoughlin accepted this revision.
dcoughlin added a comment.
This revision is now accepted and ready to land.

LGTM. I have a suggestion for a slight modification of the diagnostic text 
inline.




Comment at: test/Analysis/implicit-ctor-undef-value.cpp:12
+// missing. Specify which field is being assigned.
+class C { // expected-warning{{Value assigned to field 'y' is garbage or 
undefined}}
+  // expected-note@-1{{Value assigned to field 'y' is garbage or 
undefined}}

I think it would be good to mention that this assignment is happening in an 
implicit constructor, since that is probably not obvious to most users.

How about: "Value assigned to field 'y' in implicit constructor is garbage or 
undefined".


https://reviews.llvm.org/D43798



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


r326254 - AMDGPU: Define FP_FAST_FMA{F} macros for amdgcn

2018-02-27 Thread Konstantin Zhuravlyov via cfe-commits
Author: kzhuravl
Date: Tue Feb 27 13:48:05 2018
New Revision: 326254

URL: http://llvm.org/viewvc/llvm-project?rev=326254&view=rev
Log:
AMDGPU: Define FP_FAST_FMA{F} macros for amdgcn

- Expand GK_*s (i.e. GFX6 -> GFX600, GFX601, etc.)
  - This allows us to choose features correctly in some cases (for example, 
fast fmaf is available on gfx600, but not gfx601)
- Move HasFMAF, HasFP64, HasLDEXPF to GPUInfo tables
- Add HasFastFMA, HasFastFMAF to GPUInfo tables
- Add missing tests

Modified:
cfe/trunk/lib/Basic/Targets/AMDGPU.cpp
cfe/trunk/lib/Basic/Targets/AMDGPU.h
cfe/trunk/test/Driver/amdgpu-macros.cl
cfe/trunk/test/Misc/target-invalid-cpu-note.c

Modified: cfe/trunk/lib/Basic/Targets/AMDGPU.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Targets/AMDGPU.cpp?rev=326254&r1=326253&r2=326254&view=diff
==
--- cfe/trunk/lib/Basic/Targets/AMDGPU.cpp (original)
+++ cfe/trunk/lib/Basic/Targets/AMDGPU.cpp Tue Feb 27 13:48:05 2018
@@ -157,49 +157,62 @@ bool AMDGPUTargetInfo::initFeatureMap(
 const std::vector &FeatureVec) const {
 
   // XXX - What does the member GPU mean if device name string passed here?
-  if (getTriple().getArch() == llvm::Triple::amdgcn) {
+  if (isAMDGCN(getTriple())) {
 if (CPU.empty())
-  CPU = "tahiti";
+  CPU = "gfx600";
 
 switch (parseAMDGCNName(CPU).Kind) {
-case GK_GFX6:
-case GK_GFX7:
-  break;
-
-case GK_GFX9:
+case GK_GFX902:
+case GK_GFX900:
   Features["gfx9-insts"] = true;
   LLVM_FALLTHROUGH;
-case GK_GFX8:
-  Features["s-memrealtime"] = true;
+case GK_GFX810:
+case GK_GFX803:
+case GK_GFX802:
+case GK_GFX801:
   Features["16-bit-insts"] = true;
   Features["dpp"] = true;
+  Features["s-memrealtime"] = true;
+  break;
+case GK_GFX704:
+case GK_GFX703:
+case GK_GFX702:
+case GK_GFX701:
+case GK_GFX700:
+case GK_GFX601:
+case GK_GFX600:
   break;
-
 case GK_NONE:
   return false;
 default:
-  llvm_unreachable("unhandled subtarget");
+  llvm_unreachable("Unhandled GPU!");
 }
   } else {
 if (CPU.empty())
   CPU = "r600";
 
 switch (parseR600Name(CPU).Kind) {
-case GK_R600:
-case GK_R700:
-case GK_EVERGREEN:
-case GK_NORTHERN_ISLANDS:
-  break;
-case GK_R600_DOUBLE_OPS:
-case GK_R700_DOUBLE_OPS:
-case GK_EVERGREEN_DOUBLE_OPS:
 case GK_CAYMAN:
+case GK_CYPRESS:
+case GK_RV770:
+case GK_RV670:
   // TODO: Add fp64 when implemented.
   break;
-case GK_NONE:
-  return false;
+case GK_TURKS:
+case GK_CAICOS:
+case GK_BARTS:
+case GK_SUMO:
+case GK_REDWOOD:
+case GK_JUNIPER:
+case GK_CEDAR:
+case GK_RV730:
+case GK_RV710:
+case GK_RS880:
+case GK_R630:
+case GK_R600:
+  break;
 default:
-  llvm_unreachable("unhandled subtarget");
+  llvm_unreachable("Unhandled GPU!");
 }
   }
 
@@ -210,6 +223,7 @@ void AMDGPUTargetInfo::adjustTargetOptio
TargetOptions &TargetOpts) const {
   bool hasFP32Denormals = false;
   bool hasFP64Denormals = false;
+  GPUInfo CGOptsGPU = parseGPUName(TargetOpts.CPU);
   for (auto &I : TargetOpts.FeaturesAsWritten) {
 if (I == "+fp32-denormals" || I == "-fp32-denormals")
   hasFP32Denormals = true;
@@ -218,46 +232,52 @@ void AMDGPUTargetInfo::adjustTargetOptio
   }
   if (!hasFP32Denormals)
 TargetOpts.Features.push_back(
-(Twine(hasFullSpeedFMAF32(TargetOpts.CPU) && !CGOpts.FlushDenorm
+(Twine(CGOptsGPU.HasFastFMAF && !CGOpts.FlushDenorm
? '+'
: '-') +
  Twine("fp32-denormals"))
 .str());
   // Always do not flush fp64 or fp16 denorms.
-  if (!hasFP64Denormals && hasFP64)
+  if (!hasFP64Denormals && CGOptsGPU.HasFP64)
 TargetOpts.Features.push_back("+fp64-fp16-denormals");
 }
 
 constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::InvalidGPU;
-constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::R600Names[];
-constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::AMDGCNNames[];
+constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::R600GPUs[];
+constexpr AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::AMDGCNGPUs[];
+
 AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseR600Name(StringRef Name) {
   const auto *Result = llvm::find_if(
-  R600Names, [Name](const GPUInfo &GPU) { return GPU.Name == Name; });
+  R600GPUs, [Name](const GPUInfo &GPU) { return GPU.Name == Name; });
 
-  if (Result == std::end(R600Names))
+  if (Result == std::end(R600GPUs))
 return InvalidGPU;
   return *Result;
 }
 
 AMDGPUTargetInfo::GPUInfo AMDGPUTargetInfo::parseAMDGCNName(StringRef Name) {
-  const auto *Result =
-  llvm::find_if(AMDGCNNames, [Name](const GPUInfo &GPU) {
-return GPU.Name == Name;
-  });
+  const auto *Result = llvm::f

[PATCH] D43747: [Attr] Fix pointer_with_type_tag assert fail for variadic

2018-02-27 Thread Joel E. Denny via Phabricator via cfe-commits
jdenny added a comment.

In https://reviews.llvm.org/D43747#1018844, @aaron.ballman wrote:

> Committed in r326057.
>
> If you're not already on IRC, I would recommend joining the #llvm channel on 
> OFTC so that you can watch for build break notifications from the build bots.


Thanks.  Can your recommend effective ways to make use of this?  Do developers 
just stay logged in all day to catch failures relevant to their work?


https://reviews.llvm.org/D43747



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


Re: r326156 - [analyzer] Logging test typo quickfix.

2018-02-27 Thread George Karpenkov via cfe-commits
should be fine now.

> On Feb 27, 2018, at 12:04 AM, Yvan Roux  wrote:
> 
> Hi George,
> 
> On 27 February 2018 at 02:31, George Karpenkov via cfe-commits
> mailto:cfe-commits@lists.llvm.org>> wrote:
>> Author: george.karpenkov
>> Date: Mon Feb 26 17:31:06 2018
>> New Revision: 326156
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=326156&view=rev
>> Log:
>> [analyzer] Logging test typo quickfix.
>> 
>> Modified:
>>cfe/trunk/test/Analysis/region_store_overflow.c
>> 
>> Modified: cfe/trunk/test/Analysis/region_store_overflow.c
>> URL: 
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/region_store_overflow.c?rev=326156&r1=326155&r2=326156&view=diff
>> ==
>> --- cfe/trunk/test/Analysis/region_store_overflow.c (original)
>> +++ cfe/trunk/test/Analysis/region_store_overflow.c Mon Feb 26 17:31:06 2018
>> @@ -1,4 +1,4 @@
>> -// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core -mllvm 
>> -debug-only MemRegion %s 2>&1 | FileCheck %s
>> +// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core -mllvm 
>> -debug-only=MemRegion %s 2>&1 | FileCheck %s
>> // REQUIRES: asserts
>> 
>> int **h;
> 
> This test is still broken on ARM bots:
> http://lab.llvm.org:8011/builders/clang-cmake-armv7-quick/builds/38/steps/ninja%20check%201/logs/FAIL%3A%20Clang%3A%3Aregion_store_overflow.c
>  
> 
> 
> Thanks
> Yvan
> 
>> 
>> ___
>> cfe-commits mailing list
>> cfe-commits@lists.llvm.org 
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits 
>> 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D41968: [libunwind][MIPS] Support MIPS floating-point registers for hard-float ABIs.

2018-02-27 Thread John Baldwin via Phabricator via cfe-commits
bsdjhb added a comment.

After thinking about this some more, I need to rework this a bit.  The choice 
of how to expose the floating point registers via getFloatingPointRegister / 
setFloatingPointRegister only affects consumers of the libunwind 
unw_get_fpreg/unw_set_fpreg.  I think a bigger factor is that we need to honor 
unwind rules in frames that describe the saved location of FP registers on the 
stack (which this patchset doesn't do).  I think that's fairly trivial for the 
case where an FP register is the same size as a GP register, and it probably 
argues for storing 32-bit FP registers as individual 'float' if that is how the 
unwind information is encoded.  I haven't yet looked to see what the 
implications would be for O32 MIPS with 64-bit FP registers.  It may be that I 
punt on that configuration for now.


https://reviews.llvm.org/D41968



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


[PATCH] D39050: Add index-while-building support to Clang

2018-02-27 Thread Marc-Andre Laperle via Phabricator via cfe-commits
malaperle added a comment.

In https://reviews.llvm.org/D39050#949185, @malaperle wrote:

> In https://reviews.llvm.org/D39050#948500, @akyrtzi wrote:
>
> > @malaperle, to clarify we are not suggesting that you write your own 
> > parser, the suggestion is to use clang in 'fast-scan' mode to get the 
> > structure of the declarations of a single file, see 
> > `CXTranslationUnit_SingleFileParse` (along with enabling skipping of 
> > bodies). We have found clang is super fast when you only try to get the 
> > structure of a file like this.
>
>
> Thank you, that sounds very useful. I will try that and get some measurements.
>
> > We can make convenient APIs to provide the syntactic structure of 
> > declarations based on their location.
>
> Perhaps just for the end-loc since it's pretty much guaranteed to be needed 
> by everyone. But if it's very straightforward, perhaps that's not needed. 
> I'll try and see.
>
> > But let's say we added the end-loc, is it enough ? If you want to implement 
> > the 'peek the definition' like Eclipse, then it is not enough, you also 
> > need to figure out if there are documentation comments associated with the 
> > declaration and also show those. Also what if you want to highlight the 
> > type signature of a function, then just storing the location of the closing 
> > brace of its body is not enough. There can be any arbitrary things you may 
> > want to get from the structure of the declaration (e.g. the parameter 
> > ranges), but we could provide an API to gather any syntactic structure info 
> > you may want.
>
> That's a very good point. I guess in the back of my mind, I have the worry 
> that one cannot extend what is stored, either for a different performance 
> trade-off or for additional things. The fact that both clang and clangd have 
> to agree on the format so that index-while-building can be used seems to make 
> it inherently not possible to extend. But perhaps it's better to not 
> overthink this for now.


I did a bit more of experimenting. For the end-loc, I changed my prototype so 
that the end-loc is not stored in the index but rather computed "on the fly" 
using SourceManager and Lexer only. For my little benchmark, I used the 
LLVM/Clang/Clangd code base which I queried for all references of "std" (the 
namespace) which is around 46K references in the index.

With end-loc in index: 3.45s on average(20 samples)
With end-loc computed on the fly: 11.33s on average(20 samples)
I also tried with Xcode but without too much success: it took about 30 secs to 
reach 45K results and then carried on for a long time and hung (although I 
didn't try to leave it for hours to see if it finished).

From my perspective, it seems that the extra time is quite substantial and it 
doesn't seem worth to save an integer per occurrence in this case.

For computing the start/end-loc of function bodies, I tried the 
SingleFileParseMode and SkipFunctionBodies separately ( as a start). The source 
I use this on looks like this:

  #include "MyClass.h"
  
  MyClass::MyClass() {
  }
  
  void MyClass::doOperation() {
  }

With SingleFileParseMode, I get several errors:

> MyClass.cpp:5:1: error: use of undeclared identifier 'MyClass'
>  MyClass.cpp:8:6: error: use of undeclared identifier 'MyClass'

Then I cannot obtain any Decl* at the position of doOperation. With 
SingleFileParseMode, I'm also a bit weary that not processing headers will 
result in many inaccuracies. From our perspective, we are more wiling to 
sacrifice disk space in order to have more accuracy and speed. For comparison, 
the index I worked with containing all end-loc for occurrences and also 
function start/end is 201M for LLVM/Clang/Clangd which is small to us.

With SkipFunctionBodies alone, I can get the Decl* but 
FunctionDecl::getSourceRange() doesn't include the body, rather, it stops after 
the arguments.
It would be very nice if we could do this cheaply but it doesn't seem possible 
with those two flags alone. What did you have in mind for implementing an "API 
to gather any syntactic structure info" ?


https://reviews.llvm.org/D39050



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


[PATCH] D43798: [analyzer] UndefinedAssignment: Fix warning message on implicit copy/move constructors.

2018-02-27 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added inline comments.



Comment at: lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp:60
   // Generate a report for this bug.
+  std::string Str;
+  llvm::raw_string_ostream OS(Str);

a.sidorin wrote:
> SmallString<128>?
*recalls how it's done* Ok!



Comment at: lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp:98
+  if (I->getInit()->IgnoreImpCasts() == StoreE) {
+OS << "Value assigned to field '" << I->getMember()->getName()
+   << "' is garbage or undefined";

a.sidorin wrote:
> May be it is better to print qualified name? Just name of member can be 
> misleading if base classes have members with same names.
I don't think this can happen in an implicit constructor. We'd jump to the 
base-class constructor in this case.


https://reviews.llvm.org/D43798



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


[PATCH] D43798: [analyzer] UndefinedAssignment: Fix warning message on implicit copy/move constructors.

2018-02-27 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 136145.
NoQ marked 2 inline comments as done.
NoQ added a comment.

Use `SmallString`.

Add some test for base-class implicit constructors to see how it currently 
works (not ideal but good enough).


https://reviews.llvm.org/D43798

Files:
  lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
  test/Analysis/implicit-ctor-undef-value.cpp

Index: test/Analysis/implicit-ctor-undef-value.cpp
===
--- /dev/null
+++ test/Analysis/implicit-ctor-undef-value.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-output=text -verify %s
+
+namespace implicit_constructor {
+struct S {
+public:
+  S() {}
+  S(const S &) {}
+};
+
+// Warning is in a weird position because the body of the constructor is
+// missing. Specify which field is being assigned.
+class C { // expected-warning{{Value assigned to field 'y' is garbage or undefined}}
+  // expected-note@-1{{Value assigned to field 'y' is garbage or undefined}}
+  int x, y;
+  S s;
+
+public:
+  C(): x(0) {}
+};
+
+void test() {
+  C c1;
+  C c2(c1); // expected-note{{Calling implicit copy constructor for 'C'}}
+}
+} // end namespace implicit_constructor
+
+
+namespace explicit_constructor {
+class C {
+  int x, y;
+
+public:
+  C(): x(0) {}
+  // It is not necessary to specify which field is being assigned to.
+  C(const C &c):
+x(c.x),
+y(c.y) // expected-warning{{Assigned value is garbage or undefined}}
+   // expected-note@-1{{Assigned value is garbage or undefined}}
+  {}
+};
+
+void test() {
+  C c1;
+  C c2(c1); // expected-note{{Calling copy constructor for 'C'}}
+}
+} // end namespace explicit_constructor
+
+
+namespace base_class_constructor {
+struct S {
+public:
+  S() {}
+  S(const S &) {}
+};
+
+class C { // expected-warning{{Value assigned to field 'y' is garbage or undefined}}
+  // expected-note@-1{{Value assigned to field 'y' is garbage or undefined}}
+  int x, y;
+  S s;
+
+public:
+  C(): x(0) {}
+};
+
+class D: public C {
+public:
+  D(): C() {}
+};
+
+void test() {
+  D d1;
+  D d2(d1); // expected-note   {{Calling implicit copy constructor for 'D'}}
+// expected-note@-1{{Calling implicit copy constructor for 'C'}}
+}
+} // end namespace base_class_constructor
Index: lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
+++ lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
@@ -51,17 +51,20 @@
   if (!N)
 return;
 
-  const char *str = "Assigned value is garbage or undefined";
-
+  static const char *const DefaultMsg =
+  "Assigned value is garbage or undefined";
   if (!BT)
-BT.reset(new BuiltinBug(this, str));
+BT.reset(new BuiltinBug(this, DefaultMsg));
 
   // Generate a report for this bug.
+  llvm::SmallString<128> Str;
+  llvm::raw_svector_ostream OS(Str);
+
   const Expr *ex = nullptr;
 
   while (StoreE) {
 if (const UnaryOperator *U = dyn_cast(StoreE)) {
-  str = "The expression is an uninitialized value. "
+  OS << "The expression is an uninitialized value. "
 "The computed value will also be garbage";
 
   ex = U->getSubExpr();
@@ -71,7 +74,7 @@
 if (const BinaryOperator *B = dyn_cast(StoreE)) {
   if (B->isCompoundAssignmentOp()) {
 if (C.getSVal(B->getLHS()).isUndef()) {
-  str = "The left expression of the compound assignment is an "
+  OS << "The left expression of the compound assignment is an "
 "uninitialized value. The computed value will also be garbage";
   ex = B->getLHS();
   break;
@@ -87,10 +90,26 @@
   ex = VD->getInit();
 }
 
+if (const auto *CD =
+dyn_cast(C.getStackFrame()->getDecl())) {
+  if (CD->isImplicit()) {
+for (auto I : CD->inits()) {
+  if (I->getInit()->IgnoreImpCasts() == StoreE) {
+OS << "Value assigned to field '" << I->getMember()->getName()
+   << "' is garbage or undefined";
+break;
+  }
+}
+  }
+}
+
 break;
   }
 
-  auto R = llvm::make_unique(*BT, str, N);
+  if (OS.str().empty())
+OS << DefaultMsg;
+
+  auto R = llvm::make_unique(*BT, OS.str(), N);
   if (ex) {
 R->addRange(ex->getSourceRange());
 bugreporter::trackNullOrUndefValue(N, ex, *R);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D39074: [libunwind][MIPS]: Add support for unwinding in N32 processes.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rUNW326250: [libunwind][MIPS]: Add support for unwinding in 
N32 processes. (authored by jhb, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D39074?vs=133660&id=136144#toc

Repository:
  rUNW libunwind

https://reviews.llvm.org/D39074

Files:
  include/__libunwind_config.h
  src/AddressSpace.hpp
  src/DwarfInstructions.hpp
  src/UnwindRegistersRestore.S
  src/UnwindRegistersSave.S
  src/libunwind.cpp

Index: src/UnwindRegistersRestore.S
===
--- src/UnwindRegistersRestore.S
+++ src/UnwindRegistersRestore.S
@@ -799,7 +799,8 @@
   l.jr r9
l.nop
 
-#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
+defined(__mips_soft_float)
 
 //
 // void libunwind::Registers_mips_o32::jumpto()
@@ -855,7 +856,7 @@
   lw$4, (4 * 4)($4)
   .set pop
 
-#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
+#elif defined(__mips64) && defined(__mips_soft_float)
 
 //
 // void libunwind::Registers_mips_newabi::jumpto()
Index: src/AddressSpace.hpp
===
--- src/AddressSpace.hpp
+++ src/AddressSpace.hpp
@@ -207,6 +207,7 @@
 return val;
   }
   uintptr_t   getP(pint_t addr);
+  uint64_tgetRegister(pint_t addr);
   static uint64_t getULEB128(pint_t &addr, pint_t end);
   static int64_t  getSLEB128(pint_t &addr, pint_t end);
 
@@ -228,6 +229,14 @@
 #endif
 }
 
+inline uint64_t LocalAddressSpace::getRegister(pint_t addr) {
+#if __SIZEOF_POINTER__ == 8 || defined(__mips64)
+  return get64(addr);
+#else
+  return get32(addr);
+#endif
+}
+
 /// Read a ULEB128 into a 64-bit word.
 inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) {
   const uint8_t *p = (uint8_t *)addr;
@@ -600,6 +609,7 @@
   uint32_t  get32(pint_t addr);
   uint64_t  get64(pint_t addr);
   pint_tgetP(pint_t addr);
+  uint64_t  getRegister(pint_t addr);
   uint64_t  getULEB128(pint_t &addr, pint_t end);
   int64_t   getSLEB128(pint_t &addr, pint_t end);
   pint_tgetEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
@@ -636,7 +646,12 @@
 }
 
 template 
-uint64_t RemoteAddressSpace::getULEB128(pint_t &addr, pint_t end) {
+typename P::uint_t OtherAddressSpace::getRegister(pint_t addr) {
+  return P::getRegister(*(uint64_t *)localCopy(addr));
+}
+
+template 
+uint64_t OtherAddressSpace::getULEB128(pint_t &addr, pint_t end) {
   uintptr_t size = (end - addr);
   LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr);
   LocalAddressSpace::pint_t sladdr = laddr;
Index: src/DwarfInstructions.hpp
===
--- src/DwarfInstructions.hpp
+++ src/DwarfInstructions.hpp
@@ -82,10 +82,10 @@
 const RegisterLocation &savedReg) {
   switch (savedReg.location) {
   case CFI_Parser::kRegisterInCFA:
-return addressSpace.getP(cfa + (pint_t)savedReg.value);
+return addressSpace.getRegister(cfa + (pint_t)savedReg.value);
 
   case CFI_Parser::kRegisterAtExpression:
-return addressSpace.getP(
+return addressSpace.getRegister(
 evaluateExpression((pint_t)savedReg.value, addressSpace,
 registers, cfa));
 
Index: src/UnwindRegistersSave.S
===
--- src/UnwindRegistersSave.S
+++ src/UnwindRegistersSave.S
@@ -116,7 +116,8 @@
   xorl  %eax, %eax# return UNW_ESUCCESS
   ret
 
-#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
+defined(__mips_soft_float)
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
@@ -172,7 +173,7 @@
   or$2, $0, $0
   .set pop
 
-#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
+#elif defined(__mips64) && defined(__mips_soft_float)
 
 #
 # extern int unw_getcontext(unw_context_t* thread_state)
Index: src/libunwind.cpp
===
--- src/libunwind.cpp
+++ src/libunwind.cpp
@@ -61,9 +61,10 @@
 # define REGISTER_KIND Registers_arm
 #elif defined(__or1k__)
 # define REGISTER_KIND Registers_or1k
-#elif defined(__mips__) && defined(_ABIO32) && defined(__mips_soft_float)
+#elif defined(__mips__) && defined(_ABIO32) && _MIPS_SIM == _ABIO32 && \
+defined(__mips_soft_float)
 # define REGISTER_KIND Registers_mips_o32
-#elif defined(__mips__) && defined(_ABI64) && defined(__mips_soft_float)
+#elif defined(__mips64) && defined(__mips_soft_float)
 # define REGISTER_KIND Registers_mips_newabi
 #elif defined(__mips__)
 # warning The MIPS architecture is not supported with this ABI and environment!
Index: include/__libunwind_config.h
===

[libunwind] r326250 - [libunwind][MIPS]: Add support for unwinding in N32 processes.

2018-02-27 Thread John Baldwin via cfe-commits
Author: jhb
Date: Tue Feb 27 13:24:02 2018
New Revision: 326250

URL: http://llvm.org/viewvc/llvm-project?rev=326250&view=rev
Log:
[libunwind][MIPS]: Add support for unwinding in N32 processes.

Summary:
N32 uses the same register context as N64.  However, N32 requires one
change to properly fetch addresses from registers stored in memory.
Since N32 is an ILP32 platform, getP() only fetches the first 32-bits
of a stored register.  For a big-endian platform this fetches the
upper 32-bits which will be zero.  To fix this, add a new
getRegister() method to AddressSpace which is responsible for
extracting the address stored in a register in memory.  This matches
getP() for all current ABIs except for N32 where it reads the 64-bit
register and returns the low 32-bits as an address.  The
DwarfInstructions::getSavedRegister() method uses
AddressSpace::getRegister() instead of AddressSpace::getP().

Reviewers: sdardis, compnerd

Reviewed By: sdardis

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

Modified:
libunwind/trunk/include/__libunwind_config.h
libunwind/trunk/src/AddressSpace.hpp
libunwind/trunk/src/DwarfInstructions.hpp
libunwind/trunk/src/UnwindRegistersRestore.S
libunwind/trunk/src/UnwindRegistersSave.S
libunwind/trunk/src/libunwind.cpp

Modified: libunwind/trunk/include/__libunwind_config.h
URL: 
http://llvm.org/viewvc/llvm-project/libunwind/trunk/include/__libunwind_config.h?rev=326250&r1=326249&r2=326250&view=diff
==
--- libunwind/trunk/include/__libunwind_config.h (original)
+++ libunwind/trunk/include/__libunwind_config.h Tue Feb 27 13:24:02 2018
@@ -71,11 +71,15 @@
 #  define _LIBUNWIND_CURSOR_SIZE 24
 #  define _LIBUNWIND_HIGHEST_DWARF_REGISTER 
_LIBUNWIND_HIGHEST_DWARF_REGISTER_OR1K
 # elif defined(__mips__)
-#  if defined(_ABIO32) && defined(__mips_soft_float)
+#  if defined(_ABIO32) && _MIPS_SIM == _ABIO32 && defined(__mips_soft_float)
 #define _LIBUNWIND_TARGET_MIPS_O32 1
 #define _LIBUNWIND_CONTEXT_SIZE 18
 #define _LIBUNWIND_CURSOR_SIZE 24
-#  elif defined(_ABI64) && defined(__mips_soft_float)
+#  elif defined(_ABIN32) && _MIPS_SIM == _ABIN32 && defined(__mips_soft_float)
+#define _LIBUNWIND_TARGET_MIPS_NEWABI 1
+#define _LIBUNWIND_CONTEXT_SIZE 35
+#define _LIBUNWIND_CURSOR_SIZE 42
+#  elif defined(_ABI64) && _MIPS_SIM == _ABI64 && defined(__mips_soft_float)
 #define _LIBUNWIND_TARGET_MIPS_NEWABI 1
 #define _LIBUNWIND_CONTEXT_SIZE 35
 #define _LIBUNWIND_CURSOR_SIZE 47

Modified: libunwind/trunk/src/AddressSpace.hpp
URL: 
http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/AddressSpace.hpp?rev=326250&r1=326249&r2=326250&view=diff
==
--- libunwind/trunk/src/AddressSpace.hpp (original)
+++ libunwind/trunk/src/AddressSpace.hpp Tue Feb 27 13:24:02 2018
@@ -207,6 +207,7 @@ public:
 return val;
   }
   uintptr_t   getP(pint_t addr);
+  uint64_tgetRegister(pint_t addr);
   static uint64_t getULEB128(pint_t &addr, pint_t end);
   static int64_t  getSLEB128(pint_t &addr, pint_t end);
 
@@ -228,6 +229,14 @@ inline uintptr_t LocalAddressSpace::getP
 #endif
 }
 
+inline uint64_t LocalAddressSpace::getRegister(pint_t addr) {
+#if __SIZEOF_POINTER__ == 8 || defined(__mips64)
+  return get64(addr);
+#else
+  return get32(addr);
+#endif
+}
+
 /// Read a ULEB128 into a 64-bit word.
 inline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) {
   const uint8_t *p = (uint8_t *)addr;
@@ -600,6 +609,7 @@ public:
   uint32_t  get32(pint_t addr);
   uint64_t  get64(pint_t addr);
   pint_tgetP(pint_t addr);
+  uint64_t  getRegister(pint_t addr);
   uint64_t  getULEB128(pint_t &addr, pint_t end);
   int64_t   getSLEB128(pint_t &addr, pint_t end);
   pint_tgetEncodedP(pint_t &addr, pint_t end, uint8_t encoding,
@@ -636,7 +646,12 @@ typename P::uint_t RemoteAddressSpace
 }
 
 template 
-uint64_t RemoteAddressSpace::getULEB128(pint_t &addr, pint_t end) {
+typename P::uint_t OtherAddressSpace::getRegister(pint_t addr) {
+  return P::getRegister(*(uint64_t *)localCopy(addr));
+}
+
+template 
+uint64_t OtherAddressSpace::getULEB128(pint_t &addr, pint_t end) {
   uintptr_t size = (end - addr);
   LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) 
localCopy(addr);
   LocalAddressSpace::pint_t sladdr = laddr;

Modified: libunwind/trunk/src/DwarfInstructions.hpp
URL: 
http://llvm.org/viewvc/llvm-project/libunwind/trunk/src/DwarfInstructions.hpp?rev=326250&r1=326249&r2=326250&view=diff
==
--- libunwind/trunk/src/DwarfInstructions.hpp (original)
+++ libunwind/trunk/src/DwarfInstructions.hpp Tue Feb 27 13:24:02 2018
@@ -82,10 +82,10 @@ typename A::pint_t DwarfInstructions::kRegisterInCFA:
-return addressSpace.getP(cfa + (pint_t)savedReg.value);
+return addressSpace.getRegister(c

[PATCH] D43791: [analyzer] Suppress MallocChecker positives in destructors with atomics.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326249: [analyzer] MallocChecker: Suppress false positives 
in shared pointers. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43791?vs=136114&id=136141#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43791

Files:
  cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  cfe/trunk/test/Analysis/NewDelete-atomics.cpp

Index: cfe/trunk/test/Analysis/NewDelete-atomics.cpp
===
--- cfe/trunk/test/Analysis/NewDelete-atomics.cpp
+++ cfe/trunk/test/Analysis/NewDelete-atomics.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s
+
+// expected-no-diagnostics
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+typedef enum memory_order {
+  memory_order_relaxed = __ATOMIC_RELAXED,
+  memory_order_consume = __ATOMIC_CONSUME,
+  memory_order_acquire = __ATOMIC_ACQUIRE,
+  memory_order_release = __ATOMIC_RELEASE,
+  memory_order_acq_rel = __ATOMIC_ACQ_REL,
+  memory_order_seq_cst = __ATOMIC_SEQ_CST
+} memory_order;
+
+class Obj {
+  int RefCnt;
+
+public:
+  int incRef() {
+return __c11_atomic_fetch_add((volatile _Atomic(int) *)&RefCnt, 1,
+  memory_order_relaxed);
+  }
+
+  int decRef() {
+return __c11_atomic_fetch_sub((volatile _Atomic(int) *)&RefCnt, 1,
+  memory_order_relaxed);
+  }
+
+  void foo();
+};
+
+class IntrusivePtr {
+  Obj *Ptr;
+
+public:
+  IntrusivePtr(Obj *Ptr) : Ptr(Ptr) {
+Ptr->incRef();
+  }
+
+  IntrusivePtr(const IntrusivePtr &Other) : Ptr(Other.Ptr) {
+Ptr->incRef();
+  }
+
+  ~IntrusivePtr() {
+  // We should not take the path on which the object is deleted.
+if (Ptr->decRef() == 1)
+  delete Ptr;
+  }
+
+  Obj *getPtr() const { return Ptr; }
+};
+
+void testDestroyLocalRefPtr() {
+  IntrusivePtr p1(new Obj());
+  {
+IntrusivePtr p2(p1);
+  }
+
+  // p1 still maintains ownership. The object is not deleted.
+  p1.getPtr()->foo(); // no-warning
+}
+
+void testDestroySymbolicRefPtr(const IntrusivePtr &p1) {
+  {
+IntrusivePtr p2(p1);
+  }
+
+  // p1 still maintains ownership. The object is not deleted.
+  p1.getPtr()->foo(); // no-warning
+}
Index: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -446,15 +446,24 @@
 // A symbol from when the primary region should have been reallocated.
 SymbolRef FailedReallocSymbol;
 
+// A C++ destructor stack frame in which memory was released. Used for
+// miscellaneous false positive suppression.
+const StackFrameContext *ReleaseDestructorLC;
+
 bool IsLeak;
 
   public:
 MallocBugVisitor(SymbolRef S, bool isLeak = false)
-   : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), IsLeak(isLeak) {}
+: Sym(S), Mode(Normal), FailedReallocSymbol(nullptr),
+  ReleaseDestructorLC(nullptr), IsLeak(isLeak) {}
+
+static void *getTag() {
+  static int Tag = 0;
+  return &Tag;
+}
 
 void Profile(llvm::FoldingSetNodeID &ID) const override {
-  static int X = 0;
-  ID.AddPointer(&X);
+  ID.AddPointer(getTag());
   ID.AddPointer(Sym);
 }
 
@@ -2822,18 +2831,40 @@
 std::shared_ptr MallocChecker::MallocBugVisitor::VisitNode(
 const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
 BugReport &BR) {
+  const Stmt *S = PathDiagnosticLocation::getStmt(N);
+  if (!S)
+return nullptr;
+
+  const LocationContext *CurrentLC = N->getLocationContext();
+
+  // If we find an atomic fetch_add or fetch_sub within the destructor in which
+  // the pointer was released (before the release), this is likely a destructor
+  // of a shared pointer.
+  // Because we don't model atomics, and also because we don't know that the
+  // original reference count is positive, we should not report use-after-frees
+  // on objects deleted in such destructors. This can probably be improved
+  // through better shared pointer modeling.
+  if (ReleaseDestructorLC) {
+if (const auto *AE = dyn_cast(S)) {
+  AtomicExpr::AtomicOp Op = AE->getOp();
+  if (Op == AtomicExpr::AO__c11_atomic_fetch_add ||
+  Op == AtomicExpr::AO__c11_atomic_fetch_sub) {
+if (ReleaseDestructorLC == CurrentLC ||
+ReleaseDestr

[PATCH] D43791: [analyzer] Suppress MallocChecker positives in destructors with atomics.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC326249: [analyzer] MallocChecker: Suppress false positives 
in shared pointers. (authored by dergachev, committed by ).

Repository:
  rL LLVM

https://reviews.llvm.org/D43791

Files:
  lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  test/Analysis/NewDelete-atomics.cpp

Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -446,15 +446,24 @@
 // A symbol from when the primary region should have been reallocated.
 SymbolRef FailedReallocSymbol;
 
+// A C++ destructor stack frame in which memory was released. Used for
+// miscellaneous false positive suppression.
+const StackFrameContext *ReleaseDestructorLC;
+
 bool IsLeak;
 
   public:
 MallocBugVisitor(SymbolRef S, bool isLeak = false)
-   : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), IsLeak(isLeak) {}
+: Sym(S), Mode(Normal), FailedReallocSymbol(nullptr),
+  ReleaseDestructorLC(nullptr), IsLeak(isLeak) {}
+
+static void *getTag() {
+  static int Tag = 0;
+  return &Tag;
+}
 
 void Profile(llvm::FoldingSetNodeID &ID) const override {
-  static int X = 0;
-  ID.AddPointer(&X);
+  ID.AddPointer(getTag());
   ID.AddPointer(Sym);
 }
 
@@ -2822,18 +2831,40 @@
 std::shared_ptr MallocChecker::MallocBugVisitor::VisitNode(
 const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
 BugReport &BR) {
+  const Stmt *S = PathDiagnosticLocation::getStmt(N);
+  if (!S)
+return nullptr;
+
+  const LocationContext *CurrentLC = N->getLocationContext();
+
+  // If we find an atomic fetch_add or fetch_sub within the destructor in which
+  // the pointer was released (before the release), this is likely a destructor
+  // of a shared pointer.
+  // Because we don't model atomics, and also because we don't know that the
+  // original reference count is positive, we should not report use-after-frees
+  // on objects deleted in such destructors. This can probably be improved
+  // through better shared pointer modeling.
+  if (ReleaseDestructorLC) {
+if (const auto *AE = dyn_cast(S)) {
+  AtomicExpr::AtomicOp Op = AE->getOp();
+  if (Op == AtomicExpr::AO__c11_atomic_fetch_add ||
+  Op == AtomicExpr::AO__c11_atomic_fetch_sub) {
+if (ReleaseDestructorLC == CurrentLC ||
+ReleaseDestructorLC->isParentOf(CurrentLC)) {
+  BR.markInvalid(getTag(), S);
+}
+  }
+}
+  }
+
   ProgramStateRef state = N->getState();
   ProgramStateRef statePrev = PrevN->getState();
 
   const RefState *RS = state->get(Sym);
   const RefState *RSPrev = statePrev->get(Sym);
   if (!RS)
 return nullptr;
 
-  const Stmt *S = PathDiagnosticLocation::getStmt(N);
-  if (!S)
-return nullptr;
-
   // FIXME: We will eventually need to handle non-statement-based events
   // (__attribute__((cleanup))).
 
@@ -2849,6 +2880,24 @@
   Msg = "Memory is released";
   StackHint = new StackHintGeneratorForSymbol(Sym,
  "Returning; memory was released");
+
+  // See if we're releasing memory while inlining a destructor (or one of
+  // its callees). If so, enable the atomic-related suppression within that
+  // destructor (and all of its callees), which would kick in while visiting
+  // other nodes (the visit order is from the bug to the graph root).
+  for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) {
+if (isa(LC->getDecl())) {
+  assert(!ReleaseDestructorLC &&
+ "There can be only one release point!");
+  ReleaseDestructorLC = LC->getCurrentStackFrame();
+  // It is unlikely that releasing memory is delegated to a destructor
+  // inside a destructor of a shared pointer, because it's fairly hard
+  // to pass the information that the pointer indeed needs to be
+  // released into it. So we're only interested in the innermost
+  // destructor.
+  break;
+}
+  }
 } else if (isRelinquished(RS, RSPrev, S)) {
   Msg = "Memory ownership is transferred";
   StackHint = new StackHintGeneratorForSymbol(Sym, "");
Index: test/Analysis/NewDelete-atomics.cpp
===
--- test/Analysis/NewDelete-atomics.cpp
+++ test/Analysis/NewDelete-atomics.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,

r326249 - [analyzer] MallocChecker: Suppress false positives in shared pointers.

2018-02-27 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Tue Feb 27 13:19:33 2018
New Revision: 326249

URL: http://llvm.org/viewvc/llvm-project?rev=326249&view=rev
Log:
[analyzer] MallocChecker: Suppress false positives in shared pointers.

Throw away MallocChecker warnings that occur after releasing a pointer within a
destructor (or its callees) after performing C11 atomic fetch_add or fetch_sub
within that destructor (or its callees).

This is an indication that the destructor's class is likely a
reference-counting pointer. The analyzer is not able to understand that the
original reference count is usually large enough to avoid most use-after-frees.

Even when the smart pointer is a local variable, we still have these false
positives that this patch suppresses, because the analyzer doesn't currently
support atomics well enough.

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

Added:
cfe/trunk/test/Analysis/NewDelete-atomics.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp?rev=326249&r1=326248&r2=326249&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/MallocChecker.cpp Tue Feb 27 13:19:33 
2018
@@ -446,15 +446,24 @@ private:
 // A symbol from when the primary region should have been reallocated.
 SymbolRef FailedReallocSymbol;
 
+// A C++ destructor stack frame in which memory was released. Used for
+// miscellaneous false positive suppression.
+const StackFrameContext *ReleaseDestructorLC;
+
 bool IsLeak;
 
   public:
 MallocBugVisitor(SymbolRef S, bool isLeak = false)
-   : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), IsLeak(isLeak) {}
+: Sym(S), Mode(Normal), FailedReallocSymbol(nullptr),
+  ReleaseDestructorLC(nullptr), IsLeak(isLeak) {}
+
+static void *getTag() {
+  static int Tag = 0;
+  return &Tag;
+}
 
 void Profile(llvm::FoldingSetNodeID &ID) const override {
-  static int X = 0;
-  ID.AddPointer(&X);
+  ID.AddPointer(getTag());
   ID.AddPointer(Sym);
 }
 
@@ -2822,6 +2831,32 @@ static SymbolRef findFailedReallocSymbol
 std::shared_ptr 
MallocChecker::MallocBugVisitor::VisitNode(
 const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
 BugReport &BR) {
+  const Stmt *S = PathDiagnosticLocation::getStmt(N);
+  if (!S)
+return nullptr;
+
+  const LocationContext *CurrentLC = N->getLocationContext();
+
+  // If we find an atomic fetch_add or fetch_sub within the destructor in which
+  // the pointer was released (before the release), this is likely a destructor
+  // of a shared pointer.
+  // Because we don't model atomics, and also because we don't know that the
+  // original reference count is positive, we should not report use-after-frees
+  // on objects deleted in such destructors. This can probably be improved
+  // through better shared pointer modeling.
+  if (ReleaseDestructorLC) {
+if (const auto *AE = dyn_cast(S)) {
+  AtomicExpr::AtomicOp Op = AE->getOp();
+  if (Op == AtomicExpr::AO__c11_atomic_fetch_add ||
+  Op == AtomicExpr::AO__c11_atomic_fetch_sub) {
+if (ReleaseDestructorLC == CurrentLC ||
+ReleaseDestructorLC->isParentOf(CurrentLC)) {
+  BR.markInvalid(getTag(), S);
+}
+  }
+}
+  }
+
   ProgramStateRef state = N->getState();
   ProgramStateRef statePrev = PrevN->getState();
 
@@ -2830,10 +2865,6 @@ std::shared_ptr Mal
   if (!RS)
 return nullptr;
 
-  const Stmt *S = PathDiagnosticLocation::getStmt(N);
-  if (!S)
-return nullptr;
-
   // FIXME: We will eventually need to handle non-statement-based events
   // (__attribute__((cleanup))).
 
@@ -2849,6 +2880,24 @@ std::shared_ptr Mal
   Msg = "Memory is released";
   StackHint = new StackHintGeneratorForSymbol(Sym,
  "Returning; memory was released");
+
+  // See if we're releasing memory while inlining a destructor (or one of
+  // its callees). If so, enable the atomic-related suppression within that
+  // destructor (and all of its callees), which would kick in while 
visiting
+  // other nodes (the visit order is from the bug to the graph root).
+  for (const LocationContext *LC = CurrentLC; LC; LC = LC->getParent()) {
+if (isa(LC->getDecl())) {
+  assert(!ReleaseDestructorLC &&
+ "There can be only one release point!");
+  ReleaseDestructorLC = LC->getCurrentStackFrame();
+  // It is unlikely that releasing memory is delegated to a destructor
+  // inside a destructor of a shared pointer, because it's fairly hard
+  // to pass the information that the pointer indeed needs to be

[PATCH] D43714: [analyzer] Don't do anything when trivial-copying an empty class object.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326247: [analyzer] Fix trivial copy for empty objects. 
(authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43714?vs=135771&id=136139#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43714

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


Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -42,19 +42,30 @@
 const CallEvent &Call) {
   SVal ThisVal;
   bool AlwaysReturnsLValue;
+  const CXXRecordDecl *ThisRD = nullptr;
   if (const CXXConstructorCall *Ctor = dyn_cast(&Call)) {
 assert(Ctor->getDecl()->isTrivial());
 assert(Ctor->getDecl()->isCopyOrMoveConstructor());
 ThisVal = Ctor->getCXXThisVal();
+ThisRD = Ctor->getDecl()->getParent();
 AlwaysReturnsLValue = false;
   } else {
 assert(cast(Call.getDecl())->isTrivial());
 assert(cast(Call.getDecl())->getOverloadedOperator() ==
OO_Equal);
 ThisVal = cast(Call).getCXXThisVal();
+ThisRD = cast(Call.getDecl())->getParent();
 AlwaysReturnsLValue = true;
   }
 
+  assert(ThisRD);
+  if (ThisRD->isEmpty()) {
+// Do nothing for empty classes. Otherwise it'd retrieve an UnknownVal
+// and bind it and RegionStore would think that the actual value
+// in this region at this offset is unknown.
+return;
+  }
+
   const LocationContext *LCtx = Pred->getLocationContext();
 
   ExplodedNodeSet Dst;
Index: cfe/trunk/test/Analysis/ctor.mm
===
--- cfe/trunk/test/Analysis/ctor.mm
+++ cfe/trunk/test/Analysis/ctor.mm
@@ -729,3 +729,23 @@
 S s;
   }
 }
+
+namespace EmptyBaseAssign {
+struct B1 {};
+struct B2 { int x; };
+struct D: public B1, public B2 {
+const D &operator=(const D &d) {
+  *((B2 *)this) = d;
+  *((B1 *)this) = d;
+  return *this;
+}
+};
+
+void test() {
+  D d1;
+  d1.x = 1;
+  D d2;
+  d2 = d1;
+  clang_analyzer_eval(d2.x == 1); // expected-warning{{TRUE}}
+}
+}


Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -42,19 +42,30 @@
 const CallEvent &Call) {
   SVal ThisVal;
   bool AlwaysReturnsLValue;
+  const CXXRecordDecl *ThisRD = nullptr;
   if (const CXXConstructorCall *Ctor = dyn_cast(&Call)) {
 assert(Ctor->getDecl()->isTrivial());
 assert(Ctor->getDecl()->isCopyOrMoveConstructor());
 ThisVal = Ctor->getCXXThisVal();
+ThisRD = Ctor->getDecl()->getParent();
 AlwaysReturnsLValue = false;
   } else {
 assert(cast(Call.getDecl())->isTrivial());
 assert(cast(Call.getDecl())->getOverloadedOperator() ==
OO_Equal);
 ThisVal = cast(Call).getCXXThisVal();
+ThisRD = cast(Call.getDecl())->getParent();
 AlwaysReturnsLValue = true;
   }
 
+  assert(ThisRD);
+  if (ThisRD->isEmpty()) {
+// Do nothing for empty classes. Otherwise it'd retrieve an UnknownVal
+// and bind it and RegionStore would think that the actual value
+// in this region at this offset is unknown.
+return;
+  }
+
   const LocationContext *LCtx = Pred->getLocationContext();
 
   ExplodedNodeSet Dst;
Index: cfe/trunk/test/Analysis/ctor.mm
===
--- cfe/trunk/test/Analysis/ctor.mm
+++ cfe/trunk/test/Analysis/ctor.mm
@@ -729,3 +729,23 @@
 S s;
   }
 }
+
+namespace EmptyBaseAssign {
+struct B1 {};
+struct B2 { int x; };
+struct D: public B1, public B2 {
+const D &operator=(const D &d) {
+  *((B2 *)this) = d;
+  *((B1 *)this) = d;
+  return *this;
+}
+};
+
+void test() {
+  D d1;
+  d1.x = 1;
+  D d2;
+  d2 = d1;
+  clang_analyzer_eval(d2.x == 1); // expected-warning{{TRUE}}
+}
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r326247 - [analyzer] Fix trivial copy for empty objects.

2018-02-27 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Tue Feb 27 13:10:08 2018
New Revision: 326247

URL: http://llvm.org/viewvc/llvm-project?rev=326247&view=rev
Log:
[analyzer] Fix trivial copy for empty objects.

The SVal for any empty C++ object is an UnknownVal. Because RegionStore does
not have binding extents, binding an empty object to an UnknownVal may
potentially overwrite existing bindings at the same offset.

Therefore, when performing a trivial copy of an empty object, don't try to
take the value of the object and bind it to the copy. Doing nothing is accurate
enough, and it doesn't screw any existing bindings.

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

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/test/Analysis/ctor.mm

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=326247&r1=326246&r2=326247&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Tue Feb 27 13:10:08 2018
@@ -42,19 +42,30 @@ void ExprEngine::performTrivialCopy(Node
 const CallEvent &Call) {
   SVal ThisVal;
   bool AlwaysReturnsLValue;
+  const CXXRecordDecl *ThisRD = nullptr;
   if (const CXXConstructorCall *Ctor = dyn_cast(&Call)) {
 assert(Ctor->getDecl()->isTrivial());
 assert(Ctor->getDecl()->isCopyOrMoveConstructor());
 ThisVal = Ctor->getCXXThisVal();
+ThisRD = Ctor->getDecl()->getParent();
 AlwaysReturnsLValue = false;
   } else {
 assert(cast(Call.getDecl())->isTrivial());
 assert(cast(Call.getDecl())->getOverloadedOperator() ==
OO_Equal);
 ThisVal = cast(Call).getCXXThisVal();
+ThisRD = cast(Call.getDecl())->getParent();
 AlwaysReturnsLValue = true;
   }
 
+  assert(ThisRD);
+  if (ThisRD->isEmpty()) {
+// Do nothing for empty classes. Otherwise it'd retrieve an UnknownVal
+// and bind it and RegionStore would think that the actual value
+// in this region at this offset is unknown.
+return;
+  }
+
   const LocationContext *LCtx = Pred->getLocationContext();
 
   ExplodedNodeSet Dst;

Modified: cfe/trunk/test/Analysis/ctor.mm
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ctor.mm?rev=326247&r1=326246&r2=326247&view=diff
==
--- cfe/trunk/test/Analysis/ctor.mm (original)
+++ cfe/trunk/test/Analysis/ctor.mm Tue Feb 27 13:10:08 2018
@@ -729,3 +729,23 @@ namespace NoCrashOnEmptyBaseOptimization
 S s;
   }
 }
+
+namespace EmptyBaseAssign {
+struct B1 {};
+struct B2 { int x; };
+struct D: public B1, public B2 {
+const D &operator=(const D &d) {
+  *((B2 *)this) = d;
+  *((B1 *)this) = d;
+  return *this;
+}
+};
+
+void test() {
+  D d1;
+  d1.x = 1;
+  D d2;
+  d2 = d1;
+  clang_analyzer_eval(d2.x == 1); // expected-warning{{TRUE}}
+}
+}


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


[PATCH] D43666: [analyzer] When constructing a temporary without construction context, track it for destruction anyway.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326246: [analyzer] Track temporaries without construction 
contexts for destruction. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43666?vs=135994&id=136138#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43666

Files:
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
  cfe/trunk/test/Analysis/temporaries.cpp

Index: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -452,6 +452,10 @@
ExplodedNode *Pred,
ExplodedNodeSet &Dst);
 
+  void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
+ ExplodedNodeSet &PreVisit,
+ ExplodedNodeSet &Dst);
+
   void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
  ExplodedNodeSet &Dst);
 
Index: cfe/trunk/test/Analysis/temporaries.cpp
===
--- cfe/trunk/test/Analysis/temporaries.cpp
+++ cfe/trunk/test/Analysis/temporaries.cpp
@@ -900,7 +900,13 @@
 
 class C {
 public:
-  ~C() { glob = 1; }
+  ~C() {
+glob = 1;
+clang_analyzer_checkInlined(true);
+#ifdef TEMPORARY_DTORS
+// expected-warning@-2{{TRUE}}
+#endif
+  }
 };
 
 C get();
@@ -913,12 +919,11 @@
   // temporaries: the return value of get() and the elidable copy constructor
   // of that return value into is(). According to the CFG, we need to cleanup
   // both of them depending on whether the temporary corresponding to the
-  // return value of get() was initialized. However, for now we don't track
-  // temporaries returned from functions, so we take the wrong branch.
+  // return value of get() was initialized. However, we didn't track
+  // temporaries returned from functions, so we took the wrong branch.
   coin && is(get()); // no-crash
-  // FIXME: We should have called the destructor, i.e. should be TRUE,
-  // at least when we inline temporary destructors.
-  clang_analyzer_eval(glob == 1); // expected-warning{{UNKNOWN}}
+  // FIXME: Should be true once we inline all destructors.
+  clang_analyzer_eval(glob); // expected-warning{{UNKNOWN}}
 }
 } // namespace dont_forget_destructor_around_logical_op
 
Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1089,6 +1089,34 @@
   }
 }
 
+void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
+   ExplodedNodeSet &PreVisit,
+   ExplodedNodeSet &Dst) {
+  // This is a fallback solution in case we didn't have a construction
+  // context when we were constructing the temporary. Otherwise the map should
+  // have been populated there.
+  if (!getAnalysisManager().options.includeTemporaryDtorsInCFG()) {
+// In case we don't have temporary destructors in the CFG, do not mark
+// the initialization - we would otherwise never clean it up.
+Dst = PreVisit;
+return;
+  }
+  StmtNodeBuilder StmtBldr(PreVisit, Dst, *currBldrCtx);
+  for (ExplodedNode *Node : PreVisit) {
+ProgramStateRef State = Node->getState();
+		const auto &Key = std::make_pair(BTE, Node->getStackFrame());
+
+if (!State->contains(Key)) {
+  // FIXME: Currently the state might also already contain the marker due to
+  // incorrect handling of temporaries bound to default parameters; for
+  // those, we currently skip the CXXBindTemporaryExpr but rely on adding
+  // temporary destructor nodes.
+  State = State->set(Key, nullptr);
+}
+StmtBldr.generateNode(BTE, Node, State);
+  }
+}
+
 namespace {
 class CollectReachableSymbolsCallback final : public SymbolVisitor {
   InvalidatedSymbols Symbols;
@@ -1251,7 +1279,9 @@
   Bldr.takeNodes(Pred);
   ExplodedNodeSet PreVisit;
   getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
-  getCheckerManager().runCheckersForPostStmt(Dst, PreVisit, S, *this);
+  ExplodedNodeSet Next;
+  VisitCXXBindTemporaryExpr(cast(S), PreVisit, Next);
+  getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this);
   Bldr.addNodes(Dst);
   break;
 }
@@ -2194,13 +2224,13 @@
Pred->getLocationContext(),

r326246 - [analyzer] Track temporaries without construction contexts for destruction.

2018-02-27 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Tue Feb 27 13:02:58 2018
New Revision: 326246

URL: http://llvm.org/viewvc/llvm-project?rev=326246&view=rev
Log:
[analyzer] Track temporaries without construction contexts for destruction.

Sometimes it is not known at compile time which temporary objects will be
constructed, eg. 'x ? A() : B()' or 'C() || D()'. In this case we track which
temporary was constructed to know how to properly call the destructor.

Once the construction context for temporaries was introduced, we moved the
tracking code to the code that investigates the construction context.

Bring back the old mechanism because construction contexts are not always
available yet - eg. in the case where a temporary is constructed without a
constructor expression, eg. returned from a function by value. The mechanism
should still go away eventually.

Additionally, fix a bug in the temporary cleanup code for the case when
construction contexts are not available, which could lead to temporaries
staying in the program state and increasing memory consumption.

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/test/Analysis/temporaries.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=326246&r1=326245&r2=326246&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Tue 
Feb 27 13:02:58 2018
@@ -452,6 +452,10 @@ public:
ExplodedNode *Pred,
ExplodedNodeSet &Dst);
 
+  void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
+ ExplodedNodeSet &PreVisit,
+ ExplodedNodeSet &Dst);
+
   void VisitCXXCatchStmt(const CXXCatchStmt *CS, ExplodedNode *Pred,
  ExplodedNodeSet &Dst);
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=326246&r1=326245&r2=326246&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Feb 27 13:02:58 2018
@@ -1089,6 +1089,34 @@ void ExprEngine::processCleanupTemporary
   }
 }
 
+void ExprEngine::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE,
+   ExplodedNodeSet &PreVisit,
+   ExplodedNodeSet &Dst) {
+  // This is a fallback solution in case we didn't have a construction
+  // context when we were constructing the temporary. Otherwise the map should
+  // have been populated there.
+  if (!getAnalysisManager().options.includeTemporaryDtorsInCFG()) {
+// In case we don't have temporary destructors in the CFG, do not mark
+// the initialization - we would otherwise never clean it up.
+Dst = PreVisit;
+return;
+  }
+  StmtNodeBuilder StmtBldr(PreVisit, Dst, *currBldrCtx);
+  for (ExplodedNode *Node : PreVisit) {
+ProgramStateRef State = Node->getState();
+   const auto &Key = std::make_pair(BTE, Node->getStackFrame());
+
+if (!State->contains(Key)) {
+  // FIXME: Currently the state might also already contain the marker due 
to
+  // incorrect handling of temporaries bound to default parameters; for
+  // those, we currently skip the CXXBindTemporaryExpr but rely on adding
+  // temporary destructor nodes.
+  State = State->set(Key, nullptr);
+}
+StmtBldr.generateNode(BTE, Node, State);
+  }
+}
+
 namespace {
 class CollectReachableSymbolsCallback final : public SymbolVisitor {
   InvalidatedSymbols Symbols;
@@ -1251,7 +1279,9 @@ void ExprEngine::Visit(const Stmt *S, Ex
   Bldr.takeNodes(Pred);
   ExplodedNodeSet PreVisit;
   getCheckerManager().runCheckersForPreStmt(PreVisit, Pred, S, *this);
-  getCheckerManager().runCheckersForPostStmt(Dst, PreVisit, S, *this);
+  ExplodedNodeSet Next;
+  VisitCXXBindTemporaryExpr(cast(S), PreVisit, Next);
+  getCheckerManager().runCheckersForPostStmt(Dst, Next, S, *this);
   Bldr.addNodes(Dst);
   break;
 }
@@ -2194,13 +2224,13 @@ void ExprEngine::processEndOfFunction(No
Pred->getLocationContext(),
Pred->getStackFrame()->getParent()));
 
-  // FIXME: We currently assert that temporaries are clear, as lifetime 
extended
-  // temporaries are not always modelled correctly. In some cases 

[PATCH] D43748: [Attr] Fix paren, comma, and omitted arg printing in some cases

2018-02-27 Thread Joel E. Denny via Phabricator via cfe-commits
jdenny updated this revision to Diff 136136.
jdenny edited the summary of this revision.
jdenny added a comment.

This addresses the comment about redundant ifs.


https://reviews.llvm.org/D43748

Files:
  include/clang/Basic/Attr.td
  lib/Parse/ParseDecl.cpp
  test/Sema/attr-print.c
  test/Sema/attr-print.cpp
  utils/TableGen/ClangAttrEmitter.cpp

Index: utils/TableGen/ClangAttrEmitter.cpp
===
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -231,6 +231,7 @@
 virtual void writePCHReadArgs(raw_ostream &OS) const = 0;
 virtual void writePCHReadDecls(raw_ostream &OS) const = 0;
 virtual void writePCHWrite(raw_ostream &OS) const = 0;
+virtual std::string getIsOmitted() const { return "false"; }
 virtual void writeValue(raw_ostream &OS) const = 0;
 virtual void writeDump(raw_ostream &OS) const = 0;
 virtual void writeDumpChildren(raw_ostream &OS) const {}
@@ -298,33 +299,39 @@
std::string(getUpperName()) + "()");
 }
 
+std::string getIsOmitted() const override {
+  if (type == "IdentifierInfo *")
+return "!get" + getUpperName().str() + "()";
+  // FIXME: Do this declaratively in Attr.td.
+  if (getAttrName() == "AllocSize")
+return "0 == get" + getUpperName().str() + "()";
+  return "false";
+}
+
 void writeValue(raw_ostream &OS) const override {
-  if (type == "FunctionDecl *") {
+  if (type == "FunctionDecl *")
 OS << "\" << get" << getUpperName()
<< "()->getNameInfo().getAsString() << \"";
-  } else if (type == "IdentifierInfo *") {
-OS << "\";\n";
-if (isOptional())
-  OS << "if (get" << getUpperName() << "()) ";
-else
-  OS << "";
-OS << "OS << get" << getUpperName() << "()->getName();\n";
-OS << "OS << \"";
-  } else if (type == "TypeSourceInfo *") {
+  else if (type == "IdentifierInfo *")
+// Some non-optional (comma required) identifier arguments can be the
+// empty string but are then recorded as a nullptr.
+OS << "\" << (get" << getUpperName() << "() ? get" << getUpperName()
+   << "()->getName() : \"\") << \"";
+  else if (type == "TypeSourceInfo *")
 OS << "\" << get" << getUpperName() << "().getAsString() << \"";
-  } else {
+  else
 OS << "\" << get" << getUpperName() << "() << \"";
-  }
 }
 
 void writeDump(raw_ostream &OS) const override {
   if (type == "FunctionDecl *" || type == "NamedDecl *") {
 OS << "OS << \" \";\n";
 OS << "dumpBareDeclRef(SA->get" << getUpperName() << "());\n"; 
   } else if (type == "IdentifierInfo *") {
-if (isOptional())
-  OS << "if (SA->get" << getUpperName() << "())\n  ";
-OS << "OS << \" \" << SA->get" << getUpperName()
+// Some non-optional (comma required) identifier arguments can be the
+// empty string but are then recorded as a nullptr.
+OS << "if (SA->get" << getUpperName() << "())\n"
+   << "  OS << \" \" << SA->get" << getUpperName()
<< "()->getName();\n";
   } else if (type == "TypeSourceInfo *") {
 OS << "OS << \" \" << SA->get" << getUpperName()
@@ -576,12 +583,15 @@
  << "Type());\n";
 }
 
+std::string getIsOmitted() const override {
+  return "!is" + getLowerName().str() + "Expr || !" + getLowerName().str()
+ + "Expr";
+}
+
 void writeValue(raw_ostream &OS) const override {
   OS << "\";\n";
-  // The aligned attribute argument expression is optional.
-  OS << "if (is" << getLowerName() << "Expr && "
- << getLowerName() << "Expr)\n";
-  OS << "  " << getLowerName() << "Expr->printPretty(OS, nullptr, Policy);\n";
+  OS << "" << getLowerName()
+ << "Expr->printPretty(OS, nullptr, Policy);\n";
   OS << "OS << \"";
 }
 
@@ -1376,33 +1386,83 @@
   continue;
 }
 
-// Fake arguments aren't part of the parsed form and should not be
-// pretty-printed.
-bool hasNonFakeArgs = llvm::any_of(
-Args, [](const std::unique_ptr &A) { return !A->isFake(); });
-
-// FIXME: always printing the parenthesis isn't the correct behavior for
-// attributes which have optional arguments that were not provided. For
-// instance: __attribute__((aligned)) will be pretty printed as
-// __attribute__((aligned())). The logic should check whether there is only
-// a single argument, and if it is optional, whether it has been provided.
-if (hasNonFakeArgs)
-  OS << "(";
 if (Spelling == "availability") {
+  OS << "(";
   writeAvailabilityValue(OS);
+  OS << ")";
 } else if (Spelling == "deprecated" || Spelling == "gnu::deprecated") {
-writeDeprecatedAttrValue(OS, Variety);
+  OS 

[PATCH] D43659: [analyzer] Don't crash when dynamic type of a concrete region is hard-set with placement new.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326245: [analyzer] Don't crash when dynamic type of a 
variable is set via placement new. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43659?vs=135572&id=136137#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43659

Files:
  cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
  cfe/trunk/test/Analysis/new-dynamic-types.cpp


Index: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -587,7 +587,15 @@
   // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
   bool Failed;
   ThisVal = StateMgr.getStoreManager().attemptDownCast(ThisVal, Ty, 
Failed);
-  assert(!Failed && "Calling an incorrectly devirtualized method");
+  if (Failed) {
+// We might have suffered some sort of placement new earlier, so
+// we're constructing in a completely unexpected storage.
+// Fall back to a generic pointer cast for this-value.
+const CXXMethodDecl *StaticMD = cast(getDecl());
+const CXXRecordDecl *StaticClass = StaticMD->getParent();
+QualType StaticTy = Ctx.getPointerType(Ctx.getRecordType(StaticClass));
+ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy);
+  }
 }
 
 if (!ThisVal.isUnknown())
Index: cfe/trunk/test/Analysis/new-dynamic-types.cpp
===
--- cfe/trunk/test/Analysis/new-dynamic-types.cpp
+++ cfe/trunk/test/Analysis/new-dynamic-types.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -std=c++11 -verify %s
+
+// expected-no-diagnostics
+
+typedef __typeof(sizeof(int)) size_t;
+
+void *operator new(size_t size, void *ptr);
+
+struct B {
+  virtual void foo();
+};
+
+struct D : public B {
+  virtual void foo() override {}
+};
+
+void test_ub() {
+  // FIXME: Potentially warn because this code is pretty weird.
+  B b;
+  new (&b) D;
+  b.foo(); // no-crash
+}
+
+void test_non_ub() {
+  char c[sizeof(D)]; // Should be enough storage.
+  new (c) D;
+  ((B *)c)->foo(); // no-crash
+}


Index: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -587,7 +587,15 @@
   // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
   bool Failed;
   ThisVal = StateMgr.getStoreManager().attemptDownCast(ThisVal, Ty, Failed);
-  assert(!Failed && "Calling an incorrectly devirtualized method");
+  if (Failed) {
+// We might have suffered some sort of placement new earlier, so
+// we're constructing in a completely unexpected storage.
+// Fall back to a generic pointer cast for this-value.
+const CXXMethodDecl *StaticMD = cast(getDecl());
+const CXXRecordDecl *StaticClass = StaticMD->getParent();
+QualType StaticTy = Ctx.getPointerType(Ctx.getRecordType(StaticClass));
+ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy);
+  }
 }
 
 if (!ThisVal.isUnknown())
Index: cfe/trunk/test/Analysis/new-dynamic-types.cpp
===
--- cfe/trunk/test/Analysis/new-dynamic-types.cpp
+++ cfe/trunk/test/Analysis/new-dynamic-types.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -std=c++11 -verify %s
+
+// expected-no-diagnostics
+
+typedef __typeof(sizeof(int)) size_t;
+
+void *operator new(size_t size, void *ptr);
+
+struct B {
+  virtual void foo();
+};
+
+struct D : public B {
+  virtual void foo() override {}
+};
+
+void test_ub() {
+  // FIXME: Potentially warn because this code is pretty weird.
+  B b;
+  new (&b) D;
+  b.foo(); // no-crash
+}
+
+void test_non_ub() {
+  char c[sizeof(D)]; // Should be enough storage.
+  new (c) D;
+  ((B *)c)->foo(); // no-crash
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r326245 - [analyzer] Don't crash when dynamic type of a variable is set via placement new.

2018-02-27 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Tue Feb 27 12:54:40 2018
New Revision: 326245

URL: http://llvm.org/viewvc/llvm-project?rev=326245&view=rev
Log:
[analyzer] Don't crash when dynamic type of a variable is set via placement new.

If a variable or an otherwise a concrete typed-value region is being
placement-new'ed into, its dynamic type may change in arbitrary manners. And
when the region is used, there may be a third type that's different from both
the static and the dynamic type. It cannot be *completely* different from the
dynamic type, but it may be a base class of the dynamic type - and in this case
there isn't (and shouldn't be) any indication anywhere in the AST that there is
a derived-to-base cast from the dynamic type to the third type.

Perform a generic cast (evalCast()) from the third type to the dynamic type
in this case. From the point of view of the SVal hierarchy, this would have
produced non-canonical SVals if we used such generic cast in the normal case,
but in this case there doesn't seem to be a better option.

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

Added:
cfe/trunk/test/Analysis/new-dynamic-types.cpp
Modified:
cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp?rev=326245&r1=326244&r2=326245&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CallEvent.cpp Tue Feb 27 12:54:40 2018
@@ -587,7 +587,15 @@ void CXXInstanceCall::getInitialStackFra
   // FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
   bool Failed;
   ThisVal = StateMgr.getStoreManager().attemptDownCast(ThisVal, Ty, 
Failed);
-  assert(!Failed && "Calling an incorrectly devirtualized method");
+  if (Failed) {
+// We might have suffered some sort of placement new earlier, so
+// we're constructing in a completely unexpected storage.
+// Fall back to a generic pointer cast for this-value.
+const CXXMethodDecl *StaticMD = cast(getDecl());
+const CXXRecordDecl *StaticClass = StaticMD->getParent();
+QualType StaticTy = Ctx.getPointerType(Ctx.getRecordType(StaticClass));
+ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy);
+  }
 }
 
 if (!ThisVal.isUnknown())

Added: cfe/trunk/test/Analysis/new-dynamic-types.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/new-dynamic-types.cpp?rev=326245&view=auto
==
--- cfe/trunk/test/Analysis/new-dynamic-types.cpp (added)
+++ cfe/trunk/test/Analysis/new-dynamic-types.cpp Tue Feb 27 12:54:40 2018
@@ -0,0 +1,28 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core -std=c++11 -verify %s
+
+// expected-no-diagnostics
+
+typedef __typeof(sizeof(int)) size_t;
+
+void *operator new(size_t size, void *ptr);
+
+struct B {
+  virtual void foo();
+};
+
+struct D : public B {
+  virtual void foo() override {}
+};
+
+void test_ub() {
+  // FIXME: Potentially warn because this code is pretty weird.
+  B b;
+  new (&b) D;
+  b.foo(); // no-crash
+}
+
+void test_non_ub() {
+  char c[sizeof(D)]; // Should be enough storage.
+  new (c) D;
+  ((B *)c)->foo(); // no-crash
+}


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


[PATCH] D43689: [analyzer] Disable constructor inlining when lifetime extension through fields occurs.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC326240: [analyzer] Disable constructor inlining when 
lifetime extending through a field. (authored by dergachev, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D43689?vs=135669&id=136133#toc

Repository:
  rC Clang

https://reviews.llvm.org/D43689

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
  test/Analysis/lifetime-extension.cpp


Index: lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -678,6 +678,11 @@
   // the fake temporary target.
   if (CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion)
 return CIP_DisallowedOnce;
+
+  // If the temporary is lifetime-extended by binding a smaller object
+  // within it to a reference, automatic destructors don't work properly.
+  if (CallOpts.IsTemporaryLifetimeExtendedViaSubobject)
+return CIP_DisallowedOnce;
 }
 
 break;
Index: lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -168,6 +168,18 @@
   break;
 }
 case ConstructionContext::TemporaryObjectKind: {
+  const auto *TOCC = cast(CC);
+  // See if we're lifetime-extended via our field. If so, take a note.
+  // Because automatic destructors aren't quite working in this case.
+  if (const auto *MTE = TOCC->getMaterializedTemporaryExpr()) {
+if (const ValueDecl *VD = MTE->getExtendingDecl()) {
+  assert(VD->getType()->isReferenceType());
+  if (VD->getType()->getPointeeType().getCanonicalType() !=
+  MTE->GetTemporaryExpr()->getType().getCanonicalType()) {
+CallOpts.IsTemporaryLifetimeExtendedViaSubobject = true;
+  }
+}
+  }
   // TODO: Support temporaries lifetime-extended via static references.
   // They'd need a getCXXStaticTempObjectRegion().
   CallOpts.IsTemporaryCtorOrDtor = true;
Index: include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
===
--- include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
@@ -65,6 +65,10 @@
 bool IsArrayCtorOrDtor = false;
 /// This call is a constructor or a destructor of a temporary value.
 bool IsTemporaryCtorOrDtor = false;
+/// This call is a constructor for a temporary that is lifetime-extended
+/// by binding a smaller object within it to a reference, for example
+/// 'const int &x = C().x;'.
+bool IsTemporaryLifetimeExtendedViaSubobject = false;
 
 EvalCallOptions() {}
   };
Index: test/Analysis/lifetime-extension.cpp
===
--- test/Analysis/lifetime-extension.cpp
+++ test/Analysis/lifetime-extension.cpp
@@ -39,18 +39,10 @@
   const int &y = A().j[1]; // no-crash
   const int &z = (A().j[1], A().j[0]); // no-crash
 
-  clang_analyzer_eval(x == 1);
-  clang_analyzer_eval(y == 3);
-  clang_analyzer_eval(z == 2);
-#ifdef TEMPORARIES
- // expected-warning@-4{{TRUE}}
- // expected-warning@-4{{TRUE}}
- // expected-warning@-4{{TRUE}}
-#else
- // expected-warning@-8{{UNKNOWN}}
- // expected-warning@-8{{UNKNOWN}}
- // expected-warning@-8{{UNKNOWN}}
-#endif
+  // FIXME: All of these should be TRUE, but constructors aren't inlined.
+  clang_analyzer_eval(x == 1); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(y == 3); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(z == 2); // expected-warning{{UNKNOWN}}
 }
 } // end namespace pr19539_crash_on_destroying_an_integer
 
@@ -144,12 +136,7 @@
 const bool &x = C(true, &after, &before).x; // no-crash
   }
   // FIXME: Should be TRUE. Should not warn about garbage value.
-  clang_analyzer_eval(after == before);
-#ifdef TEMPORARIES
-  // expected-warning@-2{{The left operand of '==' is a garbage value}}
-#else
-  // expected-warning@-4{{UNKNOWN}}
-#endif
+  clang_analyzer_eval(after == before); // expected-warning{{UNKNOWN}}
 }
 } // end namespace maintain_original_object_address_on_lifetime_extension
 


Index: lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -678,6 +678,11 @@
   // the fake temporary target.
   if (CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion)
 return CIP_DisallowedOnce;
+
+  // If the temporary is lifetime-extended by binding a smal

r326240 - [analyzer] Disable constructor inlining when lifetime extending through a field.

2018-02-27 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Tue Feb 27 12:14:06 2018
New Revision: 326240

URL: http://llvm.org/viewvc/llvm-project?rev=326240&view=rev
Log:
[analyzer] Disable constructor inlining when lifetime extending through a field.

Automatic destructors are missing in the CFG in situations like

  const int &x = C().x;

For now it's better to disable construction inlining, because inlining
constructors while doing nothing on destructors is very bad.

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
cfe/trunk/test/Analysis/lifetime-extension.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=326240&r1=326239&r2=326240&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Tue 
Feb 27 12:14:06 2018
@@ -65,6 +65,10 @@ public:
 bool IsArrayCtorOrDtor = false;
 /// This call is a constructor or a destructor of a temporary value.
 bool IsTemporaryCtorOrDtor = false;
+/// This call is a constructor for a temporary that is lifetime-extended
+/// by binding a smaller object within it to a reference, for example
+/// 'const int &x = C().x;'.
+bool IsTemporaryLifetimeExtendedViaSubobject = false;
 
 EvalCallOptions() {}
   };

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=326240&r1=326239&r2=326240&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Tue Feb 27 12:14:06 2018
@@ -168,6 +168,18 @@ ExprEngine::getRegionForConstructedObjec
   break;
 }
 case ConstructionContext::TemporaryObjectKind: {
+  const auto *TOCC = cast(CC);
+  // See if we're lifetime-extended via our field. If so, take a note.
+  // Because automatic destructors aren't quite working in this case.
+  if (const auto *MTE = TOCC->getMaterializedTemporaryExpr()) {
+if (const ValueDecl *VD = MTE->getExtendingDecl()) {
+  assert(VD->getType()->isReferenceType());
+  if (VD->getType()->getPointeeType().getCanonicalType() !=
+  MTE->GetTemporaryExpr()->getType().getCanonicalType()) {
+CallOpts.IsTemporaryLifetimeExtendedViaSubobject = true;
+  }
+}
+  }
   // TODO: Support temporaries lifetime-extended via static references.
   // They'd need a getCXXStaticTempObjectRegion().
   CallOpts.IsTemporaryCtorOrDtor = true;

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=326240&r1=326239&r2=326240&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Tue Feb 27 
12:14:06 2018
@@ -678,6 +678,11 @@ ExprEngine::mayInlineCallKind(const Call
   // the fake temporary target.
   if (CallOpts.IsCtorOrDtorWithImproperlyModeledTargetRegion)
 return CIP_DisallowedOnce;
+
+  // If the temporary is lifetime-extended by binding a smaller object
+  // within it to a reference, automatic destructors don't work properly.
+  if (CallOpts.IsTemporaryLifetimeExtendedViaSubobject)
+return CIP_DisallowedOnce;
 }
 
 break;

Modified: cfe/trunk/test/Analysis/lifetime-extension.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/lifetime-extension.cpp?rev=326240&r1=326239&r2=326240&view=diff
==
--- cfe/trunk/test/Analysis/lifetime-extension.cpp (original)
+++ cfe/trunk/test/Analysis/lifetime-extension.cpp Tue Feb 27 12:14:06 2018
@@ -39,18 +39,10 @@ void f() {
   const int &y = A().j[1]; // no-crash
   const int &z = (A().j[1], A().j[0]); // no-crash
 
-  clang_analyzer_eval(x == 1);
-  clang_analyzer_eval(y == 3);
-  clang_analyzer_eval(z == 2);
-#ifdef TEMPORARIES
- // expected-warning@-4{{TRUE}}
- // expected-warning@-4{{TRUE}}
- // expected-warning@-4{{TRUE}}
-#else
- // expected-warning@-8{{UNKNOWN}}
- // expected-warning@-8{{UNKNOWN}}
- // expected-warning@-8{{UNKNOWN}}
-#endif
+  // FIXME: All of these should be TRUE, but constructors aren't inlined.
+  clang_analyzer_eval(x == 1); // expe

[PATCH] D43689: [analyzer] Disable constructor inlining when lifetime extension through fields occurs.

2018-02-27 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ added inline comments.



Comment at: include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h:70
+/// by binding a smaller object within it to a reference.
+bool IsTemporaryLifetimeExtendedViaSubobject = false;
 

dcoughlin wrote:
> Would you be willing to add a tiny code example to the comment? I.e., `const 
> int &x = C().x`
Fixed in the commit.


Repository:
  rC Clang

https://reviews.llvm.org/D43689



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


[PATCH] D43657: [analyzer] dump() dynamic type info and taint into state dumps.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326239: [analyzer] Self-debug: Dump dynamic type info and 
taint with the program state. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43657?vs=135560&id=136130#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43657

Files:
  cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
  cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp


Index: cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
@@ -47,5 +47,28 @@
   return NewState;
 }
 
+void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
+  const char *NL, const char *Sep) {
+  bool First = true;
+  for (const auto &I : State->get()) {
+if (First) {
+  Out << NL << "Dynamic types of regions:" << NL;
+  First = false;
+}
+const MemRegion *MR = I.first;
+const DynamicTypeInfo &DTI = I.second;
+Out << MR << " : ";
+if (DTI.isValid()) {
+  Out << DTI.getType()->getPointeeType().getAsString();
+  if (DTI.canBeASubClass()) {
+Out << " (or its subclass)";
+  }
+} else {
+  Out << "Invalid type info";
+}
+Out << NL;
+  }
+}
+
 } // namespace ento
 } // namespace clang
Index: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -17,6 +17,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -449,6 +450,12 @@
   // Print out the constraints.
   Mgr.getConstraintManager().print(this, Out, NL, Sep);
 
+  // Print out the tracked dynamic types.
+  printDynamicTypeInfo(this, Out, NL, Sep);
+
+  // Print out tainted symbols.
+  printTaint(Out, NL, Sep);
+
   // Print checker-specific data.
   Mgr.getOwningEngine()->printState(Out, this, NL, Sep, LC);
 }
@@ -466,7 +473,7 @@
   TaintMapImpl TM = get();
 
   if (!TM.isEmpty())
-Out <<"Tainted Symbols:" << NL;
+Out <<"Tainted symbols:" << NL;
 
   for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
 Out << I->first << " : " << I->second << NL;
Index: 
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
===
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
@@ -51,6 +51,9 @@
 DynamicTypeInfo(NewTy, CanBeSubClassed));
 }
 
+void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
+  const char *NL, const char *Sep);
+
 } // ento
 } // clang
 


Index: cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
@@ -47,5 +47,28 @@
   return NewState;
 }
 
+void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
+  const char *NL, const char *Sep) {
+  bool First = true;
+  for (const auto &I : State->get()) {
+if (First) {
+  Out << NL << "Dynamic types of regions:" << NL;
+  First = false;
+}
+const MemRegion *MR = I.first;
+const DynamicTypeInfo &DTI = I.second;
+Out << MR << " : ";
+if (DTI.isValid()) {
+  Out << DTI.getType()->getPointeeType().getAsString();
+  if (DTI.canBeASubClass()) {
+Out << " (or its subclass)";
+  }
+} else {
+  Out << "Invalid type info";
+}
+Out << NL;
+  }
+}
+
 } // namespace ento
 } // namespace clang
Index: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -17,6 +17,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -449,6 +450,12 @@
   // Print out the constraints.
   Mg

[PATCH] D43657: [analyzer] dump() dynamic type info and taint into state dumps.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC326239: [analyzer] Self-debug: Dump dynamic type info and 
taint with the program state. (authored by dergachev, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D43657

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
  lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
  lib/StaticAnalyzer/Core/ProgramState.cpp


Index: include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
===
--- include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
@@ -51,6 +51,9 @@
 DynamicTypeInfo(NewTy, CanBeSubClassed));
 }
 
+void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
+  const char *NL, const char *Sep);
+
 } // ento
 } // clang
 
Index: lib/StaticAnalyzer/Core/ProgramState.cpp
===
--- lib/StaticAnalyzer/Core/ProgramState.cpp
+++ lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -17,6 +17,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -449,6 +450,12 @@
   // Print out the constraints.
   Mgr.getConstraintManager().print(this, Out, NL, Sep);
 
+  // Print out the tracked dynamic types.
+  printDynamicTypeInfo(this, Out, NL, Sep);
+
+  // Print out tainted symbols.
+  printTaint(Out, NL, Sep);
+
   // Print checker-specific data.
   Mgr.getOwningEngine()->printState(Out, this, NL, Sep, LC);
 }
@@ -466,7 +473,7 @@
   TaintMapImpl TM = get();
 
   if (!TM.isEmpty())
-Out <<"Tainted Symbols:" << NL;
+Out <<"Tainted symbols:" << NL;
 
   for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
 Out << I->first << " : " << I->second << NL;
Index: lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
===
--- lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
+++ lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
@@ -47,5 +47,28 @@
   return NewState;
 }
 
+void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
+  const char *NL, const char *Sep) {
+  bool First = true;
+  for (const auto &I : State->get()) {
+if (First) {
+  Out << NL << "Dynamic types of regions:" << NL;
+  First = false;
+}
+const MemRegion *MR = I.first;
+const DynamicTypeInfo &DTI = I.second;
+Out << MR << " : ";
+if (DTI.isValid()) {
+  Out << DTI.getType()->getPointeeType().getAsString();
+  if (DTI.canBeASubClass()) {
+Out << " (or its subclass)";
+  }
+} else {
+  Out << "Invalid type info";
+}
+Out << NL;
+  }
+}
+
 } // namespace ento
 } // namespace clang


Index: include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
===
--- include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
+++ include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
@@ -51,6 +51,9 @@
 DynamicTypeInfo(NewTy, CanBeSubClassed));
 }
 
+void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
+  const char *NL, const char *Sep);
+
 } // ento
 } // clang
 
Index: lib/StaticAnalyzer/Core/ProgramState.cpp
===
--- lib/StaticAnalyzer/Core/ProgramState.cpp
+++ lib/StaticAnalyzer/Core/ProgramState.cpp
@@ -17,6 +17,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -449,6 +450,12 @@
   // Print out the constraints.
   Mgr.getConstraintManager().print(this, Out, NL, Sep);
 
+  // Print out the tracked dynamic types.
+  printDynamicTypeInfo(this, Out, NL, Sep);
+
+  // Print out tainted symbols.
+  printTaint(Out, NL, Sep);
+
   // Print checker-specific data.
   Mgr.getOwningEngine()->printState(Out, this, NL, Sep, LC);
 }
@@ -466,7 +473,7 @@
   TaintMapImpl TM = get();
 
   if (!TM.isEmpty())
-Out <<"Tainted Symbols:" << NL;
+Out <<"Tainted symbols:" << NL;
 
   for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
 Out << I->first << " : " << I->second << NL;
Index: lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
===
--- lib/StaticAnalyzer/Cor

r326239 - [analyzer] Self-debug: Dump dynamic type info and taint with the program state.

2018-02-27 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Tue Feb 27 12:06:20 2018
New Revision: 326239

URL: http://llvm.org/viewvc/llvm-project?rev=326239&view=rev
Log:
[analyzer] Self-debug: Dump dynamic type info and taint with the program state.

Useful for debugging problems with dynamic type info and taint.

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp

Modified: 
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h?rev=326239&r1=326238&r2=326239&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h 
Tue Feb 27 12:06:20 2018
@@ -51,6 +51,9 @@ inline ProgramStateRef setDynamicTypeInf
 DynamicTypeInfo(NewTy, CanBeSubClassed));
 }
 
+void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
+  const char *NL, const char *Sep);
+
 } // ento
 } // clang
 

Modified: cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp?rev=326239&r1=326238&r2=326239&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/DynamicTypeMap.cpp Tue Feb 27 12:06:20 
2018
@@ -47,5 +47,28 @@ ProgramStateRef setDynamicTypeInfo(Progr
   return NewState;
 }
 
+void printDynamicTypeInfo(ProgramStateRef State, raw_ostream &Out,
+  const char *NL, const char *Sep) {
+  bool First = true;
+  for (const auto &I : State->get()) {
+if (First) {
+  Out << NL << "Dynamic types of regions:" << NL;
+  First = false;
+}
+const MemRegion *MR = I.first;
+const DynamicTypeInfo &DTI = I.second;
+Out << MR << " : ";
+if (DTI.isValid()) {
+  Out << DTI.getType()->getPointeeType().getAsString();
+  if (DTI.canBeASubClass()) {
+Out << " (or its subclass)";
+  }
+} else {
+  Out << "Invalid type info";
+}
+Out << NL;
+  }
+}
+
 } // namespace ento
 } // namespace clang

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp?rev=326239&r1=326238&r2=326239&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ProgramState.cpp Tue Feb 27 12:06:20 2018
@@ -17,6 +17,7 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/SubEngine.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/TaintManager.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/DynamicTypeMap.h"
 #include "llvm/Support/raw_ostream.h"
 
 using namespace clang;
@@ -449,6 +450,12 @@ void ProgramState::print(raw_ostream &Ou
   // Print out the constraints.
   Mgr.getConstraintManager().print(this, Out, NL, Sep);
 
+  // Print out the tracked dynamic types.
+  printDynamicTypeInfo(this, Out, NL, Sep);
+
+  // Print out tainted symbols.
+  printTaint(Out, NL, Sep);
+
   // Print checker-specific data.
   Mgr.getOwningEngine()->printState(Out, this, NL, Sep, LC);
 }
@@ -466,7 +473,7 @@ void ProgramState::printTaint(raw_ostrea
   TaintMapImpl TM = get();
 
   if (!TM.isEmpty())
-Out <<"Tainted Symbols:" << NL;
+Out <<"Tainted symbols:" << NL;
 
   for (TaintMapImpl::iterator I = TM.begin(), E = TM.end(); I != E; ++I) {
 Out << I->first << " : " << I->second << NL;


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


[PATCH] D43533: [CFG] [analyzer] NFC: Refactor ConstructionContext into a finite set of cases.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326238: [CFG] NFC: Refactor ConstructionContext into a 
finite set of cases. (authored by dergachev, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43533?vs=135667&id=136128#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43533

Files:
  cfe/trunk/include/clang/Analysis/CFG.h
  cfe/trunk/include/clang/Analysis/ConstructionContext.h
  cfe/trunk/lib/Analysis/CFG.cpp
  cfe/trunk/lib/Analysis/CMakeLists.txt
  cfe/trunk/lib/Analysis/ConstructionContext.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp

Index: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -12,6 +12,7 @@
 //===--===//
 
 #include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
+#include "clang/Analysis/ConstructionContext.h"
 #include "clang/AST/DeclCXX.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/ParentMap.h"
@@ -111,47 +112,20 @@
   // See if we're constructing an existing region by looking at the
   // current construction context.
   if (CC) {
-if (const Stmt *TriggerStmt = CC->getTriggerStmt()) {
-  if (const CXXNewExpr *CNE = dyn_cast(TriggerStmt)) {
-if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
-  // TODO: Detect when the allocator returns a null pointer.
-  // Constructor shall not be called in this case.
-  if (const SubRegion *MR = dyn_cast_or_null(
-  getCXXNewAllocatorValue(State, CNE, LCtx).getAsRegion())) {
-if (CNE->isArray()) {
-  // TODO: In fact, we need to call the constructor for every
-  // allocated element, not just the first one!
-  CallOpts.IsArrayCtorOrDtor = true;
-  return getStoreManager().GetElementZeroRegion(
-  MR, CNE->getType()->getPointeeType());
-}
-return MR;
-  }
-}
-  } else if (auto *DS = dyn_cast(TriggerStmt)) {
-const auto *Var = cast(DS->getSingleDecl());
-SVal LValue = State->getLValue(Var, LCtx);
-QualType Ty = Var->getType();
-LValue = makeZeroElementRegion(State, LValue, Ty,
-   CallOpts.IsArrayCtorOrDtor);
-return LValue.getAsRegion();
-  } else if (isa(TriggerStmt)) {
-// TODO: We should construct into a CXXBindTemporaryExpr or a
-// MaterializeTemporaryExpr around the call-expression on the previous
-// stack frame. Currently we re-bind the temporary to the correct region
-// later, but that's not semantically correct. This of course does not
-// apply when we're in the top frame. But if we are in an inlined
-// function, we should be able to take the call-site CFG element,
-// and it should contain (but right now it wouldn't) some sort of
-// construction context that'd give us the right temporary expression.
-CallOpts.IsTemporaryCtorOrDtor = true;
-return MRMgr.getCXXTempObjectRegion(CE, LCtx);
-  } else if (isa(TriggerStmt)) {
-CallOpts.IsTemporaryCtorOrDtor = true;
-return MRMgr.getCXXTempObjectRegion(CE, LCtx);
-  }
-  // TODO: Consider other directly initialized elements.
-} else if (const CXXCtorInitializer *Init = CC->getTriggerInit()) {
+switch (CC->getKind()) {
+case ConstructionContext::SimpleVariableKind: {
+  const auto *DSCC = cast(CC);
+  const auto *DS = DSCC->getDeclStmt();
+  const auto *Var = cast(DS->getSingleDecl());
+  SVal LValue = State->getLValue(Var, LCtx);
+  QualType Ty = Var->getType();
+  LValue =
+  makeZeroElementRegion(State, LValue, Ty, CallOpts.IsArrayCtorOrDtor);
+  return LValue.getAsRegion();
+}
+case ConstructionContext::ConstructorInitializerKind: {
+  const auto *ICC = cast(CC);
+  const auto *Init = ICC->getCXXCtorInitializer();
   assert(Init->isAnyMemberInitializer());
   const CXXMethodDecl *CurCtor = cast(LCtx->getDecl());
   Loc ThisPtr =
@@ -173,10 +147,45 @@
CallOpts.IsArrayCtorOrDtor);
   return FieldVal.getAsRegion();
 }
-
-// FIXME: This will eventually need to handle new-expressions as well.
-// Don't forget to update the pre-constructor initialization code in
-// ExprEngine::VisitCXXConstructExpr.
+case ConstructionContext::NewAllocatedObjectKind: {
+  if (AMgr.getAnalyzerOptions().mayInlineCXXAllocator()) {
+const auto *NECC = cast(CC);
+const auto *NE = NECC->getCXXNewExpr();
+// TODO: Detect when the allocat

r326238 - [CFG] NFC: Refactor ConstructionContext into a finite set of cases.

2018-02-27 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Tue Feb 27 12:03:35 2018
New Revision: 326238

URL: http://llvm.org/viewvc/llvm-project?rev=326238&view=rev
Log:
[CFG] NFC: Refactor ConstructionContext into a finite set of cases.

ConstructionContext is moved into a separate translation unit and is separated
into multiple classes. The "old" "raw" ConstructionContext is renamed into
ConstructionContextLayer - which corresponds to the idea of building the context
gradually layer-by-layer, but it isn't easy to use in the clients. Once
CXXConstructExpr is reached, layers that we've gathered so far are transformed
into the actual, "new-style" "flat" ConstructionContext, which is put into the
CFGConstructor element and has no layers whatsoever (until it actually needs
them, eg. aggregate initialization). The new-style ConstructionContext is
instead presented as a variety of sub-classes that enumerate different ways of
constructing an object in C++. There are 5 of these supported for now,
which is around a half of what needs to be supported.

The layer-by-layer buildup process is still a little bit weird, but it hides
all the weirdness in one place, that sounds like a good thing.

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

Added:
cfe/trunk/include/clang/Analysis/ConstructionContext.h
cfe/trunk/lib/Analysis/ConstructionContext.cpp
Modified:
cfe/trunk/include/clang/Analysis/CFG.h
cfe/trunk/lib/Analysis/CFG.cpp
cfe/trunk/lib/Analysis/CMakeLists.txt
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp

Modified: cfe/trunk/include/clang/Analysis/CFG.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CFG.h?rev=326238&r1=326237&r2=326238&view=diff
==
--- cfe/trunk/include/clang/Analysis/CFG.h (original)
+++ cfe/trunk/include/clang/Analysis/CFG.h Tue Feb 27 12:03:35 2018
@@ -38,6 +38,7 @@ namespace clang {
 class ASTContext;
 class BinaryOperator;
 class CFG;
+class ConstructionContext;
 class CXXBaseSpecifier;
 class CXXBindTemporaryExpr;
 class CXXCtorInitializer;
@@ -140,94 +141,6 @@ protected:
   CFGStmt() = default;
 };
 
-// This is bulky data for CFGConstructor which would not fit into the
-// CFGElement's room (pair of pointers). Contains the information
-// necessary to express what memory is being initialized by
-// the construction.
-class ConstructionContext {
-public:
-  typedef llvm::PointerUnion TriggerTy;
-
-private:
-  // The construction site - the statement that triggered the construction
-  // for one of its parts. For instance, stack variable declaration statement
-  // triggers construction of itself or its elements if it's an array,
-  // new-expression triggers construction of the newly allocated object(s).
-  TriggerTy Trigger;
-
-  // Sometimes a single trigger is not enough to describe the construction 
site.
-  // In this case we'd have a chain of "partial" construction contexts.
-  // Some examples:
-  // - A constructor within in an aggregate initializer list within a variable
-  //   would have a construction context of the initializer list with the 
parent
-  //   construction context of a variable.
-  // - A constructor for a temporary that needs to be both destroyed
-  //   and materialized into an elidable copy constructor would have a
-  //   construction context of a CXXBindTemporaryExpr with the parent
-  //   construction context of a MaterializeTemproraryExpr.
-  // Not all of these are currently supported.
-  const ConstructionContext *Parent = nullptr;
-
-  ConstructionContext() = default;
-  ConstructionContext(TriggerTy Trigger, const ConstructionContext *Parent)
-  : Trigger(Trigger), Parent(Parent) {}
-
-public:
-  static const ConstructionContext *
-  create(BumpVectorContext &C, TriggerTy Trigger,
- const ConstructionContext *Parent = nullptr) {
-ConstructionContext *CC = C.getAllocator().Allocate();
-return new (CC) ConstructionContext(Trigger, Parent);
-  }
-
-  bool isNull() const { return Trigger.isNull(); }
-
-  TriggerTy getTrigger() const { return Trigger; }
-  const ConstructionContext *getParent() const { return Parent; }
-
-  const Stmt *getTriggerStmt() const {
-return Trigger.dyn_cast();
-  }
-
-  const CXXCtorInitializer *getTriggerInit() const {
-return Trigger.dyn_cast();
-  }
-
-  const MaterializeTemporaryExpr *getMaterializedTemporary() const {
-// TODO: Be more careful to ensure that there's only one MTE around.
-for (const ConstructionContext *CC = this; CC; CC = CC->getParent()) {
-  if (const auto *MTE = dyn_cast_or_null(
-  CC->getTriggerStmt())) {
-return MTE;
-  }
-}
-return nullptr;
-  }
-
-  bool isSameAsPartialContext(const ConstructionContext *Other) const {
-assert(Other);
-return (Trigger == Other->Trigger);
-  }
-
-  // See if Other is a proper initial segment of this construction context

[PATCH] D43497: [analyzer] Introduce correct lifetime extension behavior in simple cases.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC326236: [analyzer] Introduce correct lifetime extension 
behavior in simple cases. (authored by dergachev, committed by ).

Repository:
  rC Clang

https://reviews.llvm.org/D43497

Files:
  include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  test/Analysis/lifetime-extension.cpp
  test/Analysis/temporaries.cpp

Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -65,6 +65,17 @@
 REGISTER_TRAIT_WITH_PROGRAMSTATE(InitializedTemporaries,
  InitializedTemporariesMap)
 
+typedef llvm::ImmutableMap,
+   const CXXTempObjectRegion *>
+TemporaryMaterializationMap;
+
+// Keeps track of temporaries that will need to be materialized later.
+// The StackFrameContext assures that nested calls due to inlined recursive
+// functions do not interfere.
+REGISTER_TRAIT_WITH_PROGRAMSTATE(TemporaryMaterializations,
+ TemporaryMaterializationMap)
+
 typedef llvm::ImmutableMap,
SVal>
@@ -255,17 +266,35 @@
   const Expr *Init = InitWithAdjustments->skipRValueSubobjectAdjustments(
   CommaLHSs, Adjustments);
 
+  // Take the region for Init, i.e. for the whole object. If we do not remember
+  // the region in which the object originally was constructed, come up with
+  // a new temporary region out of thin air and copy the contents of the object
+  // (which are currently present in the Environment, because Init is an rvalue)
+  // into that region. This is not correct, but it is better than nothing.
+  bool FoundOriginalMaterializationRegion = false;
   const TypedValueRegion *TR = nullptr;
   if (const MaterializeTemporaryExpr *MT =
   dyn_cast(Result)) {
-StorageDuration SD = MT->getStorageDuration();
-// If this object is bound to a reference with static storage duration, we
-// put it in a different region to prevent "address leakage" warnings.
-if (SD == SD_Static || SD == SD_Thread)
-  TR = MRMgr.getCXXStaticTempObjectRegion(Init);
-  }
-  if (!TR)
+auto Key = std::make_pair(MT, LC->getCurrentStackFrame());
+if (const CXXTempObjectRegion *const *TRPtr =
+State->get(Key)) {
+  FoundOriginalMaterializationRegion = true;
+  TR = *TRPtr;
+  assert(TR);
+  State = State->remove(Key);
+} else {
+  StorageDuration SD = MT->getStorageDuration();
+  // If this object is bound to a reference with static storage duration, we
+  // put it in a different region to prevent "address leakage" warnings.
+  if (SD == SD_Static || SD == SD_Thread) {
+TR = MRMgr.getCXXStaticTempObjectRegion(Init);
+  } else {
+TR = MRMgr.getCXXTempObjectRegion(Init, LC);
+  }
+}
+  } else {
 TR = MRMgr.getCXXTempObjectRegion(Init, LC);
+  }
 
   SVal Reg = loc::MemRegionVal(TR);
   SVal BaseReg = Reg;
@@ -287,41 +316,46 @@
 }
   }
 
-  // What remains is to copy the value of the object to the new region.
-  // FIXME: In other words, what we should always do is copy value of the
-  // Init expression (which corresponds to the bigger object) to the whole
-  // temporary region TR. However, this value is often no longer present
-  // in the Environment. If it has disappeared, we instead invalidate TR.
-  // Still, what we can do is assign the value of expression Ex (which
-  // corresponds to the sub-object) to the TR's sub-region Reg. At least,
-  // values inside Reg would be correct.
-  SVal InitVal = State->getSVal(Init, LC);
-  if (InitVal.isUnknown()) {
-InitVal = getSValBuilder().conjureSymbolVal(Result, LC, Init->getType(),
-currBldrCtx->blockCount());
-State = State->bindLoc(BaseReg.castAs(), InitVal, LC, false);
-
-// Then we'd need to take the value that certainly exists and bind it over.
-if (InitValWithAdjustments.isUnknown()) {
-  // Try to recover some path sensitivity in case we couldn't
-  // compute the value.
-  InitValWithAdjustments = getSValBuilder().conjureSymbolVal(
-  Result, LC, InitWithAdjustments->getType(),
-  currBldrCtx->blockCount());
+  if (!FoundOriginalMaterializationRegion) {
+// What remains is to copy the value of the object to the new region.
+// FIXME: In other words, what we should always do is copy value of the
+// Init expression (which corresponds to the bigger object) to the whole
+// temporary region TR. However, this value is often no longer present
+// in the Environment. If it has disappeared, we instead invalidate TR.
+// Still, what we can do is assign the value of expression Ex (which
+// corresponds to the sub-object)

r326236 - [analyzer] Introduce correct lifetime extension behavior in simple cases.

2018-02-27 Thread Artem Dergachev via cfe-commits
Author: dergachev
Date: Tue Feb 27 11:47:49 2018
New Revision: 326236

URL: http://llvm.org/viewvc/llvm-project?rev=326236&view=rev
Log:
[analyzer] Introduce correct lifetime extension behavior in simple cases.

This patch uses the reference to MaterializeTemporaryExpr stored in the
construction context since r326014 in order to model that expression correctly.

When modeling MaterializeTemporaryExpr, instead of copying the raw memory
contents from the sub-expression's rvalue to a completely new temporary region,
that we conjure up for the lack of better options, we now have the better
option to recall the region into which the object was originally constructed
and declare that region to be the value of the expression, which is semantically
correct.

This only works when the construction context is available, which is worked on
independently.

The temporary region's liveness (in the sense of removeDeadBindings) is extended
until the MaterializeTemporaryExpr is resolved, in order to keep the store
bindings around, because it wouldn't be referenced from anywhere else in the
program state.

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

Modified:
cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
cfe/trunk/test/Analysis/lifetime-extension.cpp
cfe/trunk/test/Analysis/temporaries.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=326236&r1=326235&r2=326236&view=diff
==
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h 
(original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Tue 
Feb 27 11:47:49 2018
@@ -708,6 +708,19 @@ private:
  const LocationContext *FromLC,
  const LocationContext *ToLC);
 
+  /// Store the region of a C++ temporary object corresponding to a
+  /// CXXBindTemporaryExpr for later destruction.
+  static ProgramStateRef addTemporaryMaterialization(
+  ProgramStateRef State, const MaterializeTemporaryExpr *MTE,
+  const LocationContext *LC, const CXXTempObjectRegion *R);
+
+  /// Check if all temporary materialization regions are clear for the given
+  /// context range (including FromLC, not including ToLC).
+  /// This is useful for assertions.
+  static bool areTemporaryMaterializationsClear(ProgramStateRef State,
+const LocationContext *FromLC,
+const LocationContext *ToLC);
+
   /// Store the region returned by operator new() so that the constructor
   /// that follows it knew what location to initialize. The value should be
   /// cleared once the respective CXXNewExpr CFGStmt element is processed.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=326236&r1=326235&r2=326236&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Tue Feb 27 11:47:49 2018
@@ -65,6 +65,17 @@ typedef llvm::ImmutableMap,
+   const CXXTempObjectRegion *>
+TemporaryMaterializationMap;
+
+// Keeps track of temporaries that will need to be materialized later.
+// The StackFrameContext assures that nested calls due to inlined recursive
+// functions do not interfere.
+REGISTER_TRAIT_WITH_PROGRAMSTATE(TemporaryMaterializations,
+ TemporaryMaterializationMap)
+
 typedef llvm::ImmutableMap,
SVal>
@@ -255,17 +266,35 @@ ExprEngine::createTemporaryRegionIfNeede
   const Expr *Init = InitWithAdjustments->skipRValueSubobjectAdjustments(
   CommaLHSs, Adjustments);
 
+  // Take the region for Init, i.e. for the whole object. If we do not remember
+  // the region in which the object originally was constructed, come up with
+  // a new temporary region out of thin air and copy the contents of the object
+  // (which are currently present in the Environment, because Init is an 
rvalue)
+  // into that region. This is not correct, but it is better than nothing.
+  bool FoundOriginalMaterializationRegion = false;
   const TypedValueRegion *TR = nullptr;
   if (const MaterializeTemporaryExpr *MT =
   dyn_cast(Result)) {
-StorageDuration SD = MT->getStorageDuration();
-// If this object is bound to a reference with static storage duration, we
-// put it in a different region to prevent "address leakage" warnings.
-if (SD == SD_Static || SD == SD_Thr

[PATCH] D42776: [Sema] Fix an assertion failure in constant expression evaluation of calls to functions with default arguments

2018-02-27 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak added inline comments.



Comment at: lib/AST/ExprConstant.cpp:5236
 if (Frame) {
-  Result.set(VD, Frame->Index);
+  Result.set({VD, Frame->Index});
   return true;

rsmith wrote:
> Hmm. We should be versioning local variables as well. Currently we'll accept 
> invalid code such as:
> 
> ```
> constexpr int f() {
>   int *p = nullptr;
>   for (int k = 0; k != 2; ++k) {
> int local_var = 0;
> if (k == 0)
>   p = &local_var;
> else
>   return *p;
>   }
> }
> static_assert(f() == 0);
> ```
I made changes to the constructor and destructor of ScopeRAII so that a version 
is pushed at the start of a new iteration. This fixes the FIXME in 
test/SemaCXX/constant-expression-cxx1y.cpp.


https://reviews.llvm.org/D42776



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


[PATCH] D42776: [Sema] Fix an assertion failure in constant expression evaluation of calls to functions with default arguments

2018-02-27 Thread Akira Hatanaka via Phabricator via cfe-commits
ahatanak updated this revision to Diff 136124.
ahatanak marked 7 inline comments as done.
ahatanak added a comment.

Address review comments.


https://reviews.llvm.org/D42776

Files:
  include/clang/AST/APValue.h
  lib/AST/APValue.cpp
  lib/AST/ExprConstant.cpp
  test/SemaCXX/constant-expression-cxx1y.cpp
  test/SemaCXX/constexpr-default-arg.cpp

Index: test/SemaCXX/constexpr-default-arg.cpp
===
--- /dev/null
+++ test/SemaCXX/constexpr-default-arg.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++1y -S -o - -emit-llvm -verify %s
+
+namespace default_arg_temporary {
+
+constexpr bool equals(const float& arg = 1.0f) {
+  return arg == 1.0f;
+}
+
+constexpr const int &x(const int &p = 0) {
+  return p;
+}
+
+struct S {
+  constexpr S(const int &a = 0) {}
+};
+
+void test_default_arg2() {
+  // This piece of code used to cause an assertion failure in
+  // CallStackFrame::createTemporary because the same MTE is used to initilize
+  // both elements of the array (see PR33140).
+  constexpr S s[2] = {};
+
+  // This piece of code used to cause an assertion failure in
+  // CallStackFrame::createTemporary because multiple CXXDefaultArgExpr share
+  // the same MTE (see PR33140).
+  static_assert(equals() && equals(), "");
+
+  // Test that constant expression evaluation produces distinct lvalues for
+  // each call.
+  static_assert(&x() != &x(), "");
+}
+
+// Check that multiple CXXDefaultInitExprs don't cause an assertion failure.
+struct A { int &&r = 0; }; // expected-warning {{binding reference member}} // expected-note {{reference member declared here}}
+struct B { A x, y; };
+B b = {};
+
+}
Index: test/SemaCXX/constant-expression-cxx1y.cpp
===
--- test/SemaCXX/constant-expression-cxx1y.cpp
+++ test/SemaCXX/constant-expression-cxx1y.cpp
@@ -852,7 +852,6 @@
   static_assert(h(2) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
   static_assert(h(3) == 0, ""); // expected-error {{constant expression}} expected-note {{in call}}
 
-  // FIXME: This function should be treated as non-constant.
   constexpr void lifetime_versus_loops() {
 int *p = 0;
 for (int i = 0; i != 2; ++i) {
@@ -862,10 +861,10 @@
   if (i)
 // This modifies the 'n' from the previous iteration of the loop outside
 // its lifetime.
-++*q;
+++*q; // expected-note {{increment of object outside its lifetime}}
 }
   }
-  static_assert((lifetime_versus_loops(), true), "");
+  static_assert((lifetime_versus_loops(), true), ""); // expected-error {{constant expression}} expected-note {{in call}}
 }
 
 namespace Bitfields {
Index: lib/AST/ExprConstant.cpp
===
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -438,8 +438,8 @@
 
 // Note that we intentionally use std::map here so that references to
 // values are stable.
-typedef std::map MapTy;
-typedef MapTy::const_iterator temp_iterator;
+typedef std::map VersionToValueMap;
+typedef std::map MapTy;
 /// Temporaries - Temporary lvalues materialized within this stack frame.
 MapTy Temporaries;
 
@@ -449,6 +449,20 @@
 /// Index - The call index of this call.
 unsigned Index;
 
+/// The stack of integers for tracking version numbers for temporaries.
+SmallVector TempVersionStack = {1};
+unsigned CurTempVersion = TempVersionStack.back();
+
+unsigned getTempVersion() const { return TempVersionStack.back(); }
+
+void pushTempVersion() {
+  TempVersionStack.push_back(++CurTempVersion);
+}
+
+void popTempVersion() {
+  TempVersionStack.pop_back();
+}
+
 // FIXME: Adding this to every 'CallStackFrame' may have a nontrivial impact
 // on the overall stack usage of deeply-recursing constexpr evaluataions.
 // (We should cache this map rather than recomputing it repeatedly.)
@@ -465,10 +479,36 @@
APValue *Arguments);
 ~CallStackFrame();
 
-APValue *getTemporary(const void *Key) {
+// Return the temporary for Key whose version number is Version.
+APValue *getTemporary(const void *Key, unsigned Version) {
+  MapTy::iterator I = Temporaries.find(Key);
+  if (I == Temporaries.end())
+return nullptr;
+  // Return an uninitialized value if the temporary is not found.
+  static APValue UninitVal;
+  VersionToValueMap::iterator J = I->second.find(Version);
+  return J == I->second.end() ? &UninitVal : &J->second;
+}
+
+// Return the current temporary for Key in the map.
+APValue *getCurrentTemporary(const void *Key) {
   MapTy::iterator I = Temporaries.find(Key);
-  return I == Temporaries.end() ? nullptr : &I->second;
+  if (I == Temporaries.end())
+return nullptr;
+  // Return an uninitialized value if all temporaries for Key have been
+  // remo

[PATCH] D43811: [MinGW, CrossWindows] Allow passing -static together with -shared

2018-02-27 Thread Martin Storsjö via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326235: [MinGW, CrossWindows] Allow passing -static together 
with -shared (authored by mstorsjo, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D43811?vs=136046&id=136121#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43811

Files:
  cfe/trunk/lib/Driver/ToolChains/CrossWindows.cpp
  cfe/trunk/lib/Driver/ToolChains/MinGW.cpp
  cfe/trunk/test/Driver/mingw-libgcc.c
  cfe/trunk/test/Driver/windows-cross.c

Index: cfe/trunk/test/Driver/mingw-libgcc.c
===
--- cfe/trunk/test/Driver/mingw-libgcc.c
+++ cfe/trunk/test/Driver/mingw-libgcc.c
@@ -2,11 +2,11 @@
 // Verified with gcc version 5.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project).
 
 // gcc, static
-// RUN: %clang -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefix=CHECK_STATIC %s
-// RUN: %clang -static -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefix=CHECK_STATIC %s
-// RUN: %clang -static-libgcc -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefix=CHECK_STATIC %s
-// RUN: %clang -static -shared -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefix=CHECK_STATIC %s
-// RUN: %clang -static-libgcc -shared -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefix=CHECK_STATIC %s
+// RUN: %clang -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefixes=CHECK_STATIC,CHECK_BDYNAMIC %s
+// RUN: %clang -static -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefixes=CHECK_STATIC,CHECK_BSTATIC %s
+// RUN: %clang -static-libgcc -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefixes=CHECK_STATIC,CHECK_BDYNAMIC %s
+// RUN: %clang -static -shared -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefixes=CHECK_STATIC,CHECK_SHARED,CHECK_BSTATIC %s
+// RUN: %clang -static-libgcc -shared -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefixes=CHECK_STATIC,CHECK_SHARED,CHECK_BDYNAMIC %s
 
 // gcc, dynamic
 // RUN: %clang -shared -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefix=CHECK_DYNAMIC %s
@@ -21,5 +21,8 @@
 // RUN: %clang --driver-mode=g++ -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefix=CHECK_DYNAMIC %s
 // RUN: %clang -shared --driver-mode=g++ -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileCheck -check-prefix=CHECK_DYNAMIC %s
 
+// CHECK_SHARED: "--shared"
+// CHECK_BSTATIC: "-Bstatic"
+// CHECK_BDYNAMIC: "-Bdynamic"
 // CHECK_STATIC: "-lgcc" "-lgcc_eh"
 // CHECK_DYNAMIC: "-lgcc_s" "-lgcc"
Index: cfe/trunk/test/Driver/windows-cross.c
===
--- cfe/trunk/test/Driver/windows-cross.c
+++ cfe/trunk/test/Driver/windows-cross.c
@@ -3,6 +3,11 @@
 
 // CHECK-BASIC-LIBCXX: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{[^"]*}}.o" "-lmsvcrt"
 
+// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -stdlib=libstdc++ -rtlib=compiler-rt -static -o /dev/null %s 2>&1 \
+// RUN:   | FileCheck %s --check-prefix CHECK-STATIC
+
+// CHECK-STATIC: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bstatic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{[^"]*}}.o" "-lmsvcrt"
+
 // RUN: %clang -### -target armv7-windows-itanium --sysroot %s/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -rtlib=compiler-rt -stdlib=libstdc++ -o /dev/null %s 2>&1 \
 // RUN:   | FileCheck %s --check-prefix CHECK-RTLIB
 
@@ -23,6 +28,11 @@
 
 // CHECK-SHARED: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bdynamic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
 
+// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -shared -rtlib=compiler-rt -stdlib=libc++ -static -o shared.dll %s 2>&1 \
+// RUN:   | FileCheck %s --check-prefix CHECK-SHARED-STATIC
+
+// CHECK-SHARED-STATIC: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bstatic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt

[PATCH] D43811: [MinGW, CrossWindows] Allow passing -static together with -shared

2018-02-27 Thread Martin Storsjö via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC326235: [MinGW, CrossWindows] Allow passing -static together 
with -shared (authored by mstorsjo, committed by ).

Repository:
  rL LLVM

https://reviews.llvm.org/D43811

Files:
  lib/Driver/ToolChains/CrossWindows.cpp
  lib/Driver/ToolChains/MinGW.cpp
  test/Driver/mingw-libgcc.c
  test/Driver/windows-cross.c

Index: lib/Driver/ToolChains/MinGW.cpp
===
--- lib/Driver/ToolChains/MinGW.cpp
+++ lib/Driver/ToolChains/MinGW.cpp
@@ -141,22 +141,21 @@
 CmdArgs.push_back("console");
   }
 
+  if (Args.hasArg(options::OPT_mdll))
+CmdArgs.push_back("--dll");
+  else if (Args.hasArg(options::OPT_shared))
+CmdArgs.push_back("--shared");
   if (Args.hasArg(options::OPT_static))
 CmdArgs.push_back("-Bstatic");
-  else {
-if (Args.hasArg(options::OPT_mdll))
-  CmdArgs.push_back("--dll");
-else if (Args.hasArg(options::OPT_shared))
-  CmdArgs.push_back("--shared");
+  else
 CmdArgs.push_back("-Bdynamic");
-if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
-  CmdArgs.push_back("-e");
-  if (TC.getArch() == llvm::Triple::x86)
-CmdArgs.push_back("_DllMainCRTStartup@12");
-  else
-CmdArgs.push_back("DllMainCRTStartup");
-  CmdArgs.push_back("--enable-auto-image-base");
-}
+  if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
+CmdArgs.push_back("-e");
+if (TC.getArch() == llvm::Triple::x86)
+  CmdArgs.push_back("_DllMainCRTStartup@12");
+else
+  CmdArgs.push_back("DllMainCRTStartup");
+CmdArgs.push_back("--enable-auto-image-base");
   }
 
   CmdArgs.push_back("-o");
Index: lib/Driver/ToolChains/CrossWindows.cpp
===
--- lib/Driver/ToolChains/CrossWindows.cpp
+++ lib/Driver/ToolChains/CrossWindows.cpp
@@ -127,7 +127,8 @@
 }
 
 CmdArgs.push_back("-shared");
-CmdArgs.push_back("-Bdynamic");
+CmdArgs.push_back(Args.hasArg(options::OPT_static) ? "-Bstatic"
+   : "-Bdynamic");
 
 CmdArgs.push_back("--enable-auto-image-base");
 
Index: test/Driver/windows-cross.c
===
--- test/Driver/windows-cross.c
+++ test/Driver/windows-cross.c
@@ -3,6 +3,11 @@
 
 // CHECK-BASIC-LIBCXX: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bdynamic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{[^"]*}}.o" "-lmsvcrt"
 
+// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -stdlib=libstdc++ -rtlib=compiler-rt -static -o /dev/null %s 2>&1 \
+// RUN:   | FileCheck %s --check-prefix CHECK-STATIC
+
+// CHECK-STATIC: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-Bstatic" "--entry" "mainCRTStartup" "--allow-multiple-definition" "-o" "{{[^"]*}}" "{{[^"]*}}.o" "-lmsvcrt"
+
 // RUN: %clang -### -target armv7-windows-itanium --sysroot %s/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -rtlib=compiler-rt -stdlib=libstdc++ -o /dev/null %s 2>&1 \
 // RUN:   | FileCheck %s --check-prefix CHECK-RTLIB
 
@@ -23,6 +28,11 @@
 
 // CHECK-SHARED: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bdynamic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
 
+// RUN: %clang -### -target armv7-windows-itanium --sysroot %S/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -shared -rtlib=compiler-rt -stdlib=libc++ -static -o shared.dll %s 2>&1 \
+// RUN:   | FileCheck %s --check-prefix CHECK-SHARED-STATIC
+
+// CHECK-SHARED-STATIC: armv7-windows-itanium-ld" "--sysroot={{.*}}/Inputs/Windows/ARM/8.1" "-m" "thumb2pe" "-shared" "-Bstatic" "--enable-auto-image-base" "--entry" "_DllMainCRTStartup" "--allow-multiple-definition" "-o" "shared.dll" "--out-implib" "shared.lib" "{{.*}}.o" "-lmsvcrt" "{{.*[\\/]}}clang_rt.builtins-arm.lib"
+
 // RUN: %clang -### -target armv7-windows-itanium --sysroot %s/Inputs/Windows/ARM/8.1 -B %S/Inputs/Windows/ARM/8.1/usr/bin -fuse-ld=ld -shared -rtlib=compiler-rt -stdlib=libc++ -nostartfiles -o shared.dll %s 2>&1 \
 // RUN:   | FileCheck %s --check-prefix CHECK-NOSTARTFILES
 
Index: test/Driver/mingw-libgcc.c
===
--- test/Driver/mingw-libgcc.c
+++ test/Driver/mingw-libgcc.c
@@ -2,11 +2,11 @@
 // Verified with gcc version 5.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 project).
 
 // gcc, static
-// RUN: %clang -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | FileChe

r326235 - [MinGW, CrossWindows] Allow passing -static together with -shared

2018-02-27 Thread Martin Storsjo via cfe-commits
Author: mstorsjo
Date: Tue Feb 27 11:42:19 2018
New Revision: 326235

URL: http://llvm.org/viewvc/llvm-project?rev=326235&view=rev
Log:
[MinGW, CrossWindows] Allow passing -static together with -shared

In these combinations, link a DLL as usual, but pass -Bstatic instead
of -Bdynamic to indicate prefering static libraries.

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

Modified:
cfe/trunk/lib/Driver/ToolChains/CrossWindows.cpp
cfe/trunk/lib/Driver/ToolChains/MinGW.cpp
cfe/trunk/test/Driver/mingw-libgcc.c
cfe/trunk/test/Driver/windows-cross.c

Modified: cfe/trunk/lib/Driver/ToolChains/CrossWindows.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/CrossWindows.cpp?rev=326235&r1=326234&r2=326235&view=diff
==
--- cfe/trunk/lib/Driver/ToolChains/CrossWindows.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/CrossWindows.cpp Tue Feb 27 11:42:19 2018
@@ -127,7 +127,8 @@ void tools::CrossWindows::Linker::Constr
 }
 
 CmdArgs.push_back("-shared");
-CmdArgs.push_back("-Bdynamic");
+CmdArgs.push_back(Args.hasArg(options::OPT_static) ? "-Bstatic"
+   : "-Bdynamic");
 
 CmdArgs.push_back("--enable-auto-image-base");
 

Modified: cfe/trunk/lib/Driver/ToolChains/MinGW.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/MinGW.cpp?rev=326235&r1=326234&r2=326235&view=diff
==
--- cfe/trunk/lib/Driver/ToolChains/MinGW.cpp (original)
+++ cfe/trunk/lib/Driver/ToolChains/MinGW.cpp Tue Feb 27 11:42:19 2018
@@ -141,22 +141,21 @@ void tools::MinGW::Linker::ConstructJob(
 CmdArgs.push_back("console");
   }
 
+  if (Args.hasArg(options::OPT_mdll))
+CmdArgs.push_back("--dll");
+  else if (Args.hasArg(options::OPT_shared))
+CmdArgs.push_back("--shared");
   if (Args.hasArg(options::OPT_static))
 CmdArgs.push_back("-Bstatic");
-  else {
-if (Args.hasArg(options::OPT_mdll))
-  CmdArgs.push_back("--dll");
-else if (Args.hasArg(options::OPT_shared))
-  CmdArgs.push_back("--shared");
+  else
 CmdArgs.push_back("-Bdynamic");
-if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
-  CmdArgs.push_back("-e");
-  if (TC.getArch() == llvm::Triple::x86)
-CmdArgs.push_back("_DllMainCRTStartup@12");
-  else
-CmdArgs.push_back("DllMainCRTStartup");
-  CmdArgs.push_back("--enable-auto-image-base");
-}
+  if (Args.hasArg(options::OPT_mdll) || Args.hasArg(options::OPT_shared)) {
+CmdArgs.push_back("-e");
+if (TC.getArch() == llvm::Triple::x86)
+  CmdArgs.push_back("_DllMainCRTStartup@12");
+else
+  CmdArgs.push_back("DllMainCRTStartup");
+CmdArgs.push_back("--enable-auto-image-base");
   }
 
   CmdArgs.push_back("-o");

Modified: cfe/trunk/test/Driver/mingw-libgcc.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/mingw-libgcc.c?rev=326235&r1=326234&r2=326235&view=diff
==
--- cfe/trunk/test/Driver/mingw-libgcc.c (original)
+++ cfe/trunk/test/Driver/mingw-libgcc.c Tue Feb 27 11:42:19 2018
@@ -2,11 +2,11 @@
 // Verified with gcc version 5.1.0 (i686-posix-dwarf-rev0, Built by MinGW-W64 
project).
 
 // gcc, static
-// RUN: %clang -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | 
FileCheck -check-prefix=CHECK_STATIC %s
-// RUN: %clang -static -v -target i686-pc-windows-gnu -rtlib=platform -### %s 
2>&1 | FileCheck -check-prefix=CHECK_STATIC %s
-// RUN: %clang -static-libgcc -v -target i686-pc-windows-gnu -rtlib=platform 
-### %s 2>&1 | FileCheck -check-prefix=CHECK_STATIC %s
-// RUN: %clang -static -shared -v -target i686-pc-windows-gnu -rtlib=platform 
-### %s 2>&1 | FileCheck -check-prefix=CHECK_STATIC %s
-// RUN: %clang -static-libgcc -shared -v -target i686-pc-windows-gnu 
-rtlib=platform -### %s 2>&1 | FileCheck -check-prefix=CHECK_STATIC %s
+// RUN: %clang -v -target i686-pc-windows-gnu -rtlib=platform -### %s 2>&1 | 
FileCheck -check-prefixes=CHECK_STATIC,CHECK_BDYNAMIC %s
+// RUN: %clang -static -v -target i686-pc-windows-gnu -rtlib=platform -### %s 
2>&1 | FileCheck -check-prefixes=CHECK_STATIC,CHECK_BSTATIC %s
+// RUN: %clang -static-libgcc -v -target i686-pc-windows-gnu -rtlib=platform 
-### %s 2>&1 | FileCheck -check-prefixes=CHECK_STATIC,CHECK_BDYNAMIC %s
+// RUN: %clang -static -shared -v -target i686-pc-windows-gnu -rtlib=platform 
-### %s 2>&1 | FileCheck 
-check-prefixes=CHECK_STATIC,CHECK_SHARED,CHECK_BSTATIC %s
+// RUN: %clang -static-libgcc -shared -v -target i686-pc-windows-gnu 
-rtlib=platform -### %s 2>&1 | FileCheck 
-check-prefixes=CHECK_STATIC,CHECK_SHARED,CHECK_BDYNAMIC %s
 
 // gcc, dynamic
 // RUN: %clang -shared -v -target i686-pc-windows-gnu -rtlib=platform -### %s 
2>&1 | FileCheck -check-prefix=CHECK_DYNA

r326234 - [analyzer] Remove redundant check

2018-02-27 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Feb 27 11:28:52 2018
New Revision: 326234

URL: http://llvm.org/viewvc/llvm-project?rev=326234&view=rev
Log:
[analyzer] Remove redundant check

There is no point in assigning void just to crash on it in the next line

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

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp?rev=326234&r1=326233&r2=326234&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/RegionStore.cpp Tue Feb 27 11:28:52 2018
@@ -1401,8 +1401,6 @@ SVal RegionStoreManager::getBinding(Regi
 T = TR->getLocationType()->getPointeeType();
   else if (const SymbolicRegion *SR = dyn_cast(MR))
 T = SR->getSymbol()->getType()->getPointeeType();
-  else if (isa(MR))
-T = Ctx.VoidTy;
 }
 assert(!T.isNull() && "Unable to auto-detect binding type!");
 assert(!T->isVoidType() && "Attempting to dereference a void pointer!");


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


r326233 - [analyzer] Only attempt to get the value of locations of known type

2018-02-27 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Feb 27 11:28:52 2018
New Revision: 326233

URL: http://llvm.org/viewvc/llvm-project?rev=326233&view=rev
Log:
[analyzer] Only attempt to get the value of locations of known type

Fixes https://bugs.llvm.org/show_bug.cgi?id=36474

In general, getSVal API should be changed so that it does not crash on
some non-obvious conditions.
It should either be updated to require a type, or to return Optional.

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

Added:
cfe/trunk/test/Analysis/novoidtypecrash.c
Modified:
cfe/trunk/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp

Modified: 
cfe/trunk/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp?rev=326233&r1=326232&r2=326233&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp Tue 
Feb 27 11:28:52 2018
@@ -73,9 +73,9 @@ void NonnullGlobalConstantsChecker::chec
 return;
 
   ProgramStateRef State = C.getState();
-  SVal V = State->getSVal(location.castAs());
 
   if (isGlobalConstString(location)) {
+SVal V = State->getSVal(location.castAs());
 Optional Constr = V.getAs();
 
 if (Constr) {

Added: cfe/trunk/test/Analysis/novoidtypecrash.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/novoidtypecrash.c?rev=326233&view=auto
==
--- cfe/trunk/test/Analysis/novoidtypecrash.c (added)
+++ cfe/trunk/test/Analysis/novoidtypecrash.c Tue Feb 27 11:28:52 2018
@@ -0,0 +1,8 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core %s
+a;
+b(void **c) { // no-crash
+  *c = a;
+  int *d;
+  b(&d);
+  *d;
+}


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


[clang-tools-extra] r326222 - add UUID to the acronyms list of objc property name checks

2018-02-27 Thread Yan Zhang via cfe-commits
Author: wizard
Date: Tue Feb 27 10:35:53 2018
New Revision: 326222

URL: http://llvm.org/viewvc/llvm-project?rev=326222&view=rev
Log:
add UUID to the acronyms list of objc property name checks

Reviewers: benhamilton, hokein

Reviewed By: benhamilton

Subscribers: klimek, cfe-commits

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

Modified:
clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp

Modified: clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp?rev=326222&r1=326221&r2=326222&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp 
(original)
+++ clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp Tue 
Feb 27 10:35:53 2018
@@ -50,6 +50,7 @@ constexpr llvm::StringLiteral DefaultSpe
 "FTP",
 "GIF",
 "GPS",
+"GUID",
 "HD",
 "HDR",
 "HTML",
@@ -87,6 +88,7 @@ constexpr llvm::StringLiteral DefaultSpe
 "UI",
 "URI",
 "URL",
+"UUID",
 "VC",
 "VOIP",
 "VPN",


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


[PATCH] D43778: [clang-tidy] Adding RestrictIncludes check to Fuchsia module

2018-02-27 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang-tidy/fuchsia/RestrictIncludesCheck.cpp:42-44
+SourceLocation Loc; ///< '#' location in the include directive
+CharSourceRange Range;  ///< SourceRange for the file name
+std::string Filename;   ///< Filename as a string

We don't really use Doxygen comments for local class stuff, so you can convert 
these into regular comments.



Comment at: clang-tidy/fuchsia/RestrictIncludesCheck.cpp:75
+for (const auto &Include : FileDirectives) {
+  auto D = Check.diag(Include.Loc, "restricted include found");
+

I believe this check will be finding transitive includes, correct? If so, maybe 
this should be two diagnostics: one to say `"'%0' is prohibited from being 
included"` and a note for the transitive case to say `"file included 
transitively from here"`?

Regardless of the behavior you'd like for it, we should have a test case:
```
// a.h
// Assumed that a.h is prohibited
void f();

// b.h
#include "a.h"

// c.c
#include "b.h"

int main() {
  f();
}
```



Comment at: clang-tidy/fuchsia/RestrictIncludesCheck.cpp:83
+
+  D << FixItHint::CreateRemoval(ToRange);
+}

Are you okay with breaking user's code from this removal? If you remove the 
header file, but not the parts of the code that require that header file to be 
included, this FixIt will break code.



Comment at: clang-tidy/fuchsia/RestrictIncludesCheck.cpp:87
+
+  IncludeDirectives.clear();
+}

Do you need to clear this? I don't think `EndOfMainFile()` can be called twice, 
can it?



Comment at: clang-tidy/fuchsia/RestrictIncludesCheck.cpp:92-95
+  for (const auto &Include : Check.getRestrictedIncludes()) {
+if (IncludeFile == Include) return true;
+  }
+  return false;

This can be replaced with: `return 
llvm::is_contained(Check.getRestrictedIncludes(), IncludeFile);` which suggests 
the private function isn't needed at all.



Comment at: clang-tidy/fuchsia/RestrictIncludesCheck.h:20
+
+/// Checks for restricted headers and suggests their removal.
+///

s/headers/includes



Comment at: clang-tidy/fuchsia/RestrictIncludesCheck.h:28
+  : ClangTidyCheck(Name, Context),
+RestrictedIncludes(utils::options::parseStringList(
+Options.get("Includes", "::std::vector"))) {}

There is a mild problem here (present in the previous form, using commas, as 
well): the separator is technically a legal character for a file name. You may 
want to provide a comment in the documentation that explicitly states a file 
with the delimiter in the name is not supported. e.g., a file named 
`foo.h;bar.h` is not something you can prohibit with this check. I don't think 
it's worth picking a different delimiter over given how unlikely this file name 
is in practice.



Comment at: clang-tidy/fuchsia/RestrictIncludesCheck.h:29
+RestrictedIncludes(utils::options::parseStringList(
+Options.get("Includes", "::std::vector"))) {}
+

The default value here seems very strange as it's not an include file. I assume 
this intended to use `vector`?



Comment at: docs/clang-tidy/checks/fuchsia-restrict-includes.rst:28
+
+   A string containing a comma-separated list of include filenames to 
restrict. Default is an empty string.

The list is not comma-separated, it's semicolon-separated.


https://reviews.llvm.org/D43778



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


[PATCH] D43811: [MinGW, CrossWindows] Allow passing -static together with -shared

2018-02-27 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo added a comment.

In https://reviews.llvm.org/D43811#1020847, @rnk wrote:

> This means, link the CRT and other default libraries statically, but give me 
> a DLL, right? Just confirming.


Exactly - for all libraries linked where you have the choice of both dynamic 
and static, pick the static one. (In mingw, you can't link the CRT statically 
though, so that, and any windows system dlls will still be linked dynamically.)


Repository:
  rC Clang

https://reviews.llvm.org/D43811



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


r326230 - [analyzer] Quickfix: don't crash when runtime definition is not available.

2018-02-27 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Feb 27 11:19:49 2018
New Revision: 326230

URL: http://llvm.org/viewvc/llvm-project?rev=326230&view=rev
Log:
[analyzer] Quickfix: don't crash when runtime definition is not available.

Modified:
cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=326230&r1=326229&r2=326230&view=diff
==
--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Tue Feb 27 
11:19:49 2018
@@ -321,9 +321,11 @@ private:
   /// Get parameters associated with runtime definition in order
   /// to get the correct parameter name.
   ArrayRef getCallParameters(CallEventRef<> Call) {
-if (isa(Call->getDecl()))
-  return dyn_cast(Call->getRuntimeDefinition().getDecl())
-  ->parameters();
+// Use runtime definition, if available.
+RuntimeDefinition RD = Call->getRuntimeDefinition();
+if (auto *FD = dyn_cast_or_null(RD.getDecl()))
+  return FD->parameters();
+
 return Call->parameters();
   }
 


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


r326229 - [analyzer] Logging test quickfix #2.

2018-02-27 Thread George Karpenkov via cfe-commits
Author: george.karpenkov
Date: Tue Feb 27 11:19:43 2018
New Revision: 326229

URL: http://llvm.org/viewvc/llvm-project?rev=326229&view=rev
Log:
[analyzer] Logging test quickfix #2.

Modified:
cfe/trunk/test/Analysis/region_store_overflow.c

Modified: cfe/trunk/test/Analysis/region_store_overflow.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/region_store_overflow.c?rev=326229&r1=326228&r2=326229&view=diff
==
--- cfe/trunk/test/Analysis/region_store_overflow.c (original)
+++ cfe/trunk/test/Analysis/region_store_overflow.c Tue Feb 27 11:19:43 2018
@@ -1,6 +1,6 @@
-// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core -mllvm 
-debug-only=MemRegion %s 2>&1 | FileCheck %s
-// REQUIRES: asserts
+// RUN: %clang_analyze_cc1 -analyze -analyzer-checker=core -verify %s
 
+// expected-no-diagnostics
 int **h;
 int overflow_in_memregion(long j) {
   for (int l = 0;; ++l) {
@@ -9,4 +9,3 @@ int overflow_in_memregion(long j) {
   }
   return 0;
 }
-// CHECK: MemRegion::getAsArrayOffset: offset overflowing, returning unknown


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


[PATCH] D43829: [Sema] Add -Wparentheses warnings for macros (PR 18971)

2018-02-27 Thread Chijun Sima via Phabricator via cfe-commits
NutshellySima added a comment.

In https://reviews.llvm.org/D43829#1020957, @lebedev.ri wrote:

> Tests?


Thanks for your advice, I'll add one.


Repository:
  rC Clang

https://reviews.llvm.org/D43829



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


[PATCH] D43791: [analyzer] Suppress MallocChecker positives in destructors with atomics.

2018-02-27 Thread Artem Dergachev via Phabricator via cfe-commits
NoQ updated this revision to Diff 136114.
NoQ added a comment.

Add one more comment.


https://reviews.llvm.org/D43791

Files:
  lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  test/Analysis/NewDelete-atomics.cpp

Index: test/Analysis/NewDelete-atomics.cpp
===
--- /dev/null
+++ test/Analysis/NewDelete-atomics.cpp
@@ -0,0 +1,74 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDelete -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,cplusplus.NewDeleteLeaks -DLEAKS -std=c++11 -DTEST_INLINABLE_ALLOCATORS -verify %s
+
+// expected-no-diagnostics
+
+#include "Inputs/system-header-simulator-cxx.h"
+
+typedef enum memory_order {
+  memory_order_relaxed = __ATOMIC_RELAXED,
+  memory_order_consume = __ATOMIC_CONSUME,
+  memory_order_acquire = __ATOMIC_ACQUIRE,
+  memory_order_release = __ATOMIC_RELEASE,
+  memory_order_acq_rel = __ATOMIC_ACQ_REL,
+  memory_order_seq_cst = __ATOMIC_SEQ_CST
+} memory_order;
+
+class Obj {
+  int RefCnt;
+
+public:
+  int incRef() {
+return __c11_atomic_fetch_add((volatile _Atomic(int) *)&RefCnt, 1,
+  memory_order_relaxed);
+  }
+
+  int decRef() {
+return __c11_atomic_fetch_sub((volatile _Atomic(int) *)&RefCnt, 1,
+  memory_order_relaxed);
+  }
+
+  void foo();
+};
+
+class IntrusivePtr {
+  Obj *Ptr;
+
+public:
+  IntrusivePtr(Obj *Ptr) : Ptr(Ptr) {
+Ptr->incRef();
+  }
+
+  IntrusivePtr(const IntrusivePtr &Other) : Ptr(Other.Ptr) {
+Ptr->incRef();
+  }
+
+  ~IntrusivePtr() {
+  // We should not take the path on which the object is deleted.
+if (Ptr->decRef() == 1)
+  delete Ptr;
+  }
+
+  Obj *getPtr() const { return Ptr; }
+};
+
+void testDestroyLocalRefPtr() {
+  IntrusivePtr p1(new Obj());
+  {
+IntrusivePtr p2(p1);
+  }
+
+  // p1 still maintains ownership. The object is not deleted.
+  p1.getPtr()->foo(); // no-warning
+}
+
+void testDestroySymbolicRefPtr(const IntrusivePtr &p1) {
+  {
+IntrusivePtr p2(p1);
+  }
+
+  // p1 still maintains ownership. The object is not deleted.
+  p1.getPtr()->foo(); // no-warning
+}
Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -446,15 +446,24 @@
 // A symbol from when the primary region should have been reallocated.
 SymbolRef FailedReallocSymbol;
 
+// A C++ destructor stack frame in which memory was released. Used for
+// miscellaneous false positive suppression.
+const StackFrameContext *ReleaseDestructorLC;
+
 bool IsLeak;
 
   public:
 MallocBugVisitor(SymbolRef S, bool isLeak = false)
-   : Sym(S), Mode(Normal), FailedReallocSymbol(nullptr), IsLeak(isLeak) {}
+: Sym(S), Mode(Normal), FailedReallocSymbol(nullptr),
+  ReleaseDestructorLC(nullptr), IsLeak(isLeak) {}
+
+static void *getTag() {
+  static int Tag = 0;
+  return &Tag;
+}
 
 void Profile(llvm::FoldingSetNodeID &ID) const override {
-  static int X = 0;
-  ID.AddPointer(&X);
+  ID.AddPointer(getTag());
   ID.AddPointer(Sym);
 }
 
@@ -2822,18 +2831,40 @@
 std::shared_ptr MallocChecker::MallocBugVisitor::VisitNode(
 const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC,
 BugReport &BR) {
+  const Stmt *S = PathDiagnosticLocation::getStmt(N);
+  if (!S)
+return nullptr;
+
+  const LocationContext *CurrentLC = N->getLocationContext();
+
+  // If we find an atomic fetch_add or fetch_sub within the destructor in which
+  // the pointer was released (before the release), this is likely a destructor
+  // of a shared pointer.
+  // Because we don't model atomics, and also because we don't know that the
+  // original reference count is positive, we should not report use-after-frees
+  // on objects deleted in such destructors. This can probably be improved
+  // through better shared pointer modeling.
+  if (ReleaseDestructorLC) {
+if (const auto *AE = dyn_cast(S)) {
+  AtomicExpr::AtomicOp Op = AE->getOp();
+  if (Op == AtomicExpr::AO__c11_atomic_fetch_add ||
+  Op == AtomicExpr::AO__c11_atomic_fetch_sub) {
+if (ReleaseDestructorLC == CurrentLC ||
+ReleaseDestructorLC->isParentOf(CurrentLC)) {
+  BR.markInvalid(getTag(), S);
+}
+  }
+}
+  }
+
   ProgramStateRef state = N->getState();
   ProgramStateRef statePrev = PrevN->getState();
 
   const RefState *RS = state->get(Sym);
   const RefState *RSPrev = statePrev->get(Sym);
   if (!RS)
 return nullptr;
 
-  const Stmt *S = PathDiagnosticLocation::getStmt(N)

[PATCH] D43830: [clang-format] Format operator key in protos

2018-02-27 Thread Krasimir Georgiev via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rC326227: [clang-format] Format operator key in protos 
(authored by krasimir, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D43830?vs=136111&id=136113#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43830

Files:
  lib/Format/TokenAnnotator.cpp
  unittests/Format/FormatTestProto.cpp
  unittests/Format/FormatTestTextProto.cpp


Index: lib/Format/TokenAnnotator.cpp
===
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -759,6 +759,9 @@
 Tok->Type = TT_BinaryOperator;
   break;
 case tok::kw_operator:
+  if (Style.Language == FormatStyle::LK_TextProto ||
+  Style.Language == FormatStyle::LK_Proto)
+break;
   while (CurrentToken &&
  !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
 if (CurrentToken->isOneOf(tok::star, tok::amp))
Index: unittests/Format/FormatTestTextProto.cpp
===
--- unittests/Format/FormatTestTextProto.cpp
+++ unittests/Format/FormatTestTextProto.cpp
@@ -440,5 +440,17 @@
   Style.Cpp11BracedListStyle = true;
   verifyFormat("keys: [1]", Style);
 }
+
+TEST_F(FormatTestTextProto, AcceptsOperatorAsKey) {
+  verifyFormat("aaa: <\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   ">");
+}
 } // end namespace tooling
 } // end namespace clang
Index: unittests/Format/FormatTestProto.cpp
===
--- unittests/Format/FormatTestProto.cpp
+++ unittests/Format/FormatTestProto.cpp
@@ -478,5 +478,17 @@
"};");
 }
 
+TEST_F(FormatTestProto, AcceptsOperatorAsKeyInOptions) {
+  verifyFormat("option (MyProto.options) = {\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   "};");
+}
+
 } // end namespace tooling
 } // end namespace clang


Index: lib/Format/TokenAnnotator.cpp
===
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -759,6 +759,9 @@
 Tok->Type = TT_BinaryOperator;
   break;
 case tok::kw_operator:
+  if (Style.Language == FormatStyle::LK_TextProto ||
+  Style.Language == FormatStyle::LK_Proto)
+break;
   while (CurrentToken &&
  !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
 if (CurrentToken->isOneOf(tok::star, tok::amp))
Index: unittests/Format/FormatTestTextProto.cpp
===
--- unittests/Format/FormatTestTextProto.cpp
+++ unittests/Format/FormatTestTextProto.cpp
@@ -440,5 +440,17 @@
   Style.Cpp11BracedListStyle = true;
   verifyFormat("keys: [1]", Style);
 }
+
+TEST_F(FormatTestTextProto, AcceptsOperatorAsKey) {
+  verifyFormat("aaa: <\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   ">");
+}
 } // end namespace tooling
 } // end namespace clang
Index: unittests/Format/FormatTestProto.cpp
===
--- unittests/Format/FormatTestProto.cpp
+++ unittests/Format/FormatTestProto.cpp
@@ -478,5 +478,17 @@
"};");
 }
 
+TEST_F(FormatTestProto, AcceptsOperatorAsKeyInOptions) {
+  verifyFormat("option (MyProto.options) = {\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   "};");
+}
+
 } // end namespace tooling
 } // end namespace clang
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43830: [clang-format] Format operator key in protos

2018-02-27 Thread Krasimir Georgiev via Phabricator via cfe-commits
krasimir created this revision.
Herald added subscribers: cfe-commits, klimek.

This fixes a glitch where ``operator: value`` in a text proto would mess up the 
underlying formatting since it gets parsed as a kw_operator instead of an 
identifier.


Repository:
  rC Clang

https://reviews.llvm.org/D43830

Files:
  lib/Format/TokenAnnotator.cpp
  unittests/Format/FormatTestProto.cpp
  unittests/Format/FormatTestTextProto.cpp


Index: unittests/Format/FormatTestTextProto.cpp
===
--- unittests/Format/FormatTestTextProto.cpp
+++ unittests/Format/FormatTestTextProto.cpp
@@ -440,5 +440,17 @@
   Style.Cpp11BracedListStyle = true;
   verifyFormat("keys: [1]", Style);
 }
+
+TEST_F(FormatTestTextProto, AcceptsOperatorAsKey) {
+  verifyFormat("aaa: <\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   ">");
+}
 } // end namespace tooling
 } // end namespace clang
Index: unittests/Format/FormatTestProto.cpp
===
--- unittests/Format/FormatTestProto.cpp
+++ unittests/Format/FormatTestProto.cpp
@@ -478,5 +478,17 @@
"};");
 }
 
+TEST_F(FormatTestProto, AcceptsOperatorAsKeyInOptions) {
+  verifyFormat("option (MyProto.options) = {\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   "};");
+}
+
 } // end namespace tooling
 } // end namespace clang
Index: lib/Format/TokenAnnotator.cpp
===
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -759,6 +759,9 @@
 Tok->Type = TT_BinaryOperator;
   break;
 case tok::kw_operator:
+  if (Style.Language == FormatStyle::LK_TextProto ||
+  Style.Language == FormatStyle::LK_Proto)
+break;
   while (CurrentToken &&
  !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
 if (CurrentToken->isOneOf(tok::star, tok::amp))


Index: unittests/Format/FormatTestTextProto.cpp
===
--- unittests/Format/FormatTestTextProto.cpp
+++ unittests/Format/FormatTestTextProto.cpp
@@ -440,5 +440,17 @@
   Style.Cpp11BracedListStyle = true;
   verifyFormat("keys: [1]", Style);
 }
+
+TEST_F(FormatTestTextProto, AcceptsOperatorAsKey) {
+  verifyFormat("aaa: <\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   ">");
+}
 } // end namespace tooling
 } // end namespace clang
Index: unittests/Format/FormatTestProto.cpp
===
--- unittests/Format/FormatTestProto.cpp
+++ unittests/Format/FormatTestProto.cpp
@@ -478,5 +478,17 @@
"};");
 }
 
+TEST_F(FormatTestProto, AcceptsOperatorAsKeyInOptions) {
+  verifyFormat("option (MyProto.options) = {\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   "};");
+}
+
 } // end namespace tooling
 } // end namespace clang
Index: lib/Format/TokenAnnotator.cpp
===
--- lib/Format/TokenAnnotator.cpp
+++ lib/Format/TokenAnnotator.cpp
@@ -759,6 +759,9 @@
 Tok->Type = TT_BinaryOperator;
   break;
 case tok::kw_operator:
+  if (Style.Language == FormatStyle::LK_TextProto ||
+  Style.Language == FormatStyle::LK_Proto)
+break;
   while (CurrentToken &&
  !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
 if (CurrentToken->isOneOf(tok::star, tok::amp))
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43830: [clang-format] Format operator key in protos

2018-02-27 Thread Krasimir Georgiev via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326227: [clang-format] Format operator key in protos 
(authored by krasimir, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D43830

Files:
  cfe/trunk/lib/Format/TokenAnnotator.cpp
  cfe/trunk/unittests/Format/FormatTestProto.cpp
  cfe/trunk/unittests/Format/FormatTestTextProto.cpp


Index: cfe/trunk/lib/Format/TokenAnnotator.cpp
===
--- cfe/trunk/lib/Format/TokenAnnotator.cpp
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp
@@ -759,6 +759,9 @@
 Tok->Type = TT_BinaryOperator;
   break;
 case tok::kw_operator:
+  if (Style.Language == FormatStyle::LK_TextProto ||
+  Style.Language == FormatStyle::LK_Proto)
+break;
   while (CurrentToken &&
  !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
 if (CurrentToken->isOneOf(tok::star, tok::amp))
Index: cfe/trunk/unittests/Format/FormatTestTextProto.cpp
===
--- cfe/trunk/unittests/Format/FormatTestTextProto.cpp
+++ cfe/trunk/unittests/Format/FormatTestTextProto.cpp
@@ -440,5 +440,17 @@
   Style.Cpp11BracedListStyle = true;
   verifyFormat("keys: [1]", Style);
 }
+
+TEST_F(FormatTestTextProto, AcceptsOperatorAsKey) {
+  verifyFormat("aaa: <\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   ">");
+}
 } // end namespace tooling
 } // end namespace clang
Index: cfe/trunk/unittests/Format/FormatTestProto.cpp
===
--- cfe/trunk/unittests/Format/FormatTestProto.cpp
+++ cfe/trunk/unittests/Format/FormatTestProto.cpp
@@ -478,5 +478,17 @@
"};");
 }
 
+TEST_F(FormatTestProto, AcceptsOperatorAsKeyInOptions) {
+  verifyFormat("option (MyProto.options) = {\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   "};");
+}
+
 } // end namespace tooling
 } // end namespace clang


Index: cfe/trunk/lib/Format/TokenAnnotator.cpp
===
--- cfe/trunk/lib/Format/TokenAnnotator.cpp
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp
@@ -759,6 +759,9 @@
 Tok->Type = TT_BinaryOperator;
   break;
 case tok::kw_operator:
+  if (Style.Language == FormatStyle::LK_TextProto ||
+  Style.Language == FormatStyle::LK_Proto)
+break;
   while (CurrentToken &&
  !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
 if (CurrentToken->isOneOf(tok::star, tok::amp))
Index: cfe/trunk/unittests/Format/FormatTestTextProto.cpp
===
--- cfe/trunk/unittests/Format/FormatTestTextProto.cpp
+++ cfe/trunk/unittests/Format/FormatTestTextProto.cpp
@@ -440,5 +440,17 @@
   Style.Cpp11BracedListStyle = true;
   verifyFormat("keys: [1]", Style);
 }
+
+TEST_F(FormatTestTextProto, AcceptsOperatorAsKey) {
+  verifyFormat("aaa: <\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   ">");
+}
 } // end namespace tooling
 } // end namespace clang
Index: cfe/trunk/unittests/Format/FormatTestProto.cpp
===
--- cfe/trunk/unittests/Format/FormatTestProto.cpp
+++ cfe/trunk/unittests/Format/FormatTestProto.cpp
@@ -478,5 +478,17 @@
"};");
 }
 
+TEST_F(FormatTestProto, AcceptsOperatorAsKeyInOptions) {
+  verifyFormat("option (MyProto.options) = {\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   "};");
+}
+
 } // end namespace tooling
 } // end namespace clang
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r326227 - [clang-format] Format operator key in protos

2018-02-27 Thread Krasimir Georgiev via cfe-commits
Author: krasimir
Date: Tue Feb 27 11:07:47 2018
New Revision: 326227

URL: http://llvm.org/viewvc/llvm-project?rev=326227&view=rev
Log:
[clang-format] Format operator key in protos

Summary: This fixes a glitch where ``operator: value`` in a text proto would 
mess up the underlying formatting since it gets parsed as a kw_operator instead 
of an identifier.

Subscribers: klimek, cfe-commits

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

Modified:
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/unittests/Format/FormatTestProto.cpp
cfe/trunk/unittests/Format/FormatTestTextProto.cpp

Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=326227&r1=326226&r2=326227&view=diff
==
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Tue Feb 27 11:07:47 2018
@@ -759,6 +759,9 @@ private:
 Tok->Type = TT_BinaryOperator;
   break;
 case tok::kw_operator:
+  if (Style.Language == FormatStyle::LK_TextProto ||
+  Style.Language == FormatStyle::LK_Proto)
+break;
   while (CurrentToken &&
  !CurrentToken->isOneOf(tok::l_paren, tok::semi, tok::r_paren)) {
 if (CurrentToken->isOneOf(tok::star, tok::amp))

Modified: cfe/trunk/unittests/Format/FormatTestProto.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestProto.cpp?rev=326227&r1=326226&r2=326227&view=diff
==
--- cfe/trunk/unittests/Format/FormatTestProto.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestProto.cpp Tue Feb 27 11:07:47 2018
@@ -478,5 +478,17 @@ TEST_F(FormatTestProto, FormatsRepeatedL
"};");
 }
 
+TEST_F(FormatTestProto, AcceptsOperatorAsKeyInOptions) {
+  verifyFormat("option (MyProto.options) = {\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   "};");
+}
+
 } // end namespace tooling
 } // end namespace clang

Modified: cfe/trunk/unittests/Format/FormatTestTextProto.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTestTextProto.cpp?rev=326227&r1=326226&r2=326227&view=diff
==
--- cfe/trunk/unittests/Format/FormatTestTextProto.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTestTextProto.cpp Tue Feb 27 11:07:47 2018
@@ -440,5 +440,17 @@ TEST_F(FormatTestTextProto, FormatsRepea
   Style.Cpp11BracedListStyle = true;
   verifyFormat("keys: [1]", Style);
 }
+
+TEST_F(FormatTestTextProto, AcceptsOperatorAsKey) {
+  verifyFormat("aaa: <\n"
+   "  b: <\n"
+   "ccc: <\n"
+   "  operator: 1\n"
+   "  operator: 2\n"
+   "  operator { key: value }\n"
+   ">\n"
+   "  >\n"
+   ">");
+}
 } // end namespace tooling
 } // end namespace clang


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


[PATCH] D43829: [Sema] Add -Wparentheses warnings for macros (PR 18971)

2018-02-27 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added a comment.

Tests?


Repository:
  rC Clang

https://reviews.llvm.org/D43829



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


[PATCH] D43829: [Sema] Add -Wparentheses warnings for macros (PR 18971)

2018-02-27 Thread Chijun Sima via Phabricator via cfe-commits
NutshellySima created this revision.
NutshellySima added a reviewer: rsmith.
Herald added a subscriber: cfe-commits.

Before, clang does not warn -Wlogical-op-parentheses and 
-Wbitwise-op-parentheses in macros, thus miss some cases like PR 18971 and 
mismatch gcc's behavior.

Fix this by enabling the warning even when the expression is in macros.

Patch by Chijun Sima.


Repository:
  rC Clang

https://reviews.llvm.org/D43829

Files:
  lib/Sema/SemaExpr.cpp


Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -12024,15 +12024,14 @@
 DiagnoseBitwisePrecedence(Self, Opc, OpLoc, LHSExpr, RHSExpr);
 
   // Diagnose "arg1 & arg2 | arg3"
-  if ((Opc == BO_Or || Opc == BO_Xor) &&
-  !OpLoc.isMacroID()/* Don't warn in macros. */) {
+  if (Opc == BO_Or || Opc == BO_Xor) {
 DiagnoseBitwiseOpInBitwiseOp(Self, Opc, OpLoc, LHSExpr);
 DiagnoseBitwiseOpInBitwiseOp(Self, Opc, OpLoc, RHSExpr);
   }
 
   // Warn about arg1 || arg2 && arg3, as GCC 4.3+ does.
   // We don't warn for 'assert(a || b && "bad")' since this is safe.
-  if (Opc == BO_LOr && !OpLoc.isMacroID()/* Don't warn in macros. */) {
+  if (Opc == BO_LOr) {
 DiagnoseLogicalAndInLogicalOrLHS(Self, OpLoc, LHSExpr, RHSExpr);
 DiagnoseLogicalAndInLogicalOrRHS(Self, OpLoc, LHSExpr, RHSExpr);
   }


Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -12024,15 +12024,14 @@
 DiagnoseBitwisePrecedence(Self, Opc, OpLoc, LHSExpr, RHSExpr);
 
   // Diagnose "arg1 & arg2 | arg3"
-  if ((Opc == BO_Or || Opc == BO_Xor) &&
-  !OpLoc.isMacroID()/* Don't warn in macros. */) {
+  if (Opc == BO_Or || Opc == BO_Xor) {
 DiagnoseBitwiseOpInBitwiseOp(Self, Opc, OpLoc, LHSExpr);
 DiagnoseBitwiseOpInBitwiseOp(Self, Opc, OpLoc, RHSExpr);
   }
 
   // Warn about arg1 || arg2 && arg3, as GCC 4.3+ does.
   // We don't warn for 'assert(a || b && "bad")' since this is safe.
-  if (Opc == BO_LOr && !OpLoc.isMacroID()/* Don't warn in macros. */) {
+  if (Opc == BO_LOr) {
 DiagnoseLogicalAndInLogicalOrLHS(Self, OpLoc, LHSExpr, RHSExpr);
 DiagnoseLogicalAndInLogicalOrRHS(Self, OpLoc, LHSExpr, RHSExpr);
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43766: [clang-tidy][modernize-make-unique] Checks c++14 flag before using std::make_unique

2018-02-27 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang-tidy/modernize/MakeSmartPtrCheck.cpp:64
 
+bool MakeSmartPtrCheck::isLanguageVersionSupported(const LangOptions & 
LangOpts) const
+{

The formatting here is wrong.


https://reviews.llvm.org/D43766



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


[PATCH] D43585: [libunwind] Permit additional compiler and linker flags to be passed to tests.

2018-02-27 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326223: [libunwind] Permit additional compiler and linker 
flags to be passed to tests. (authored by jhb, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D43585

Files:
  libunwind/trunk/CMakeLists.txt
  libunwind/trunk/test/lit.site.cfg.in


Index: libunwind/trunk/test/lit.site.cfg.in
===
--- libunwind/trunk/test/lit.site.cfg.in
+++ libunwind/trunk/test/lit.site.cfg.in
@@ -12,6 +12,8 @@
 config.use_sanitizer= "@LLVM_USE_SANITIZER@"
 config.enable_32bit = "@LIBUNWIND_BUILD_32_BITS@"
 config.target_info  = "@LIBUNWIND_TARGET_INFO@"
+config.test_linker_flags= "@LIBUNWIND_TEST_LINKER_FLAGS@"
+config.test_compiler_flags  = "@LIBUNWIND_TEST_COMPILER_FLAGS@"
 config.executor = "@LIBUNWIND_EXECUTOR@"
 config.libunwind_shared = "@LIBUNWIND_ENABLE_SHARED@"
 config.enable_shared= "@LIBCXX_ENABLE_SHARED@"
Index: libunwind/trunk/CMakeLists.txt
===
--- libunwind/trunk/CMakeLists.txt
+++ libunwind/trunk/CMakeLists.txt
@@ -139,6 +139,10 @@
 set(LIBUNWIND_TARGET_TRIPLE "" CACHE STRING "Target triple for cross 
compiling.")
 set(LIBUNWIND_GCC_TOOLCHAIN "" CACHE PATH "GCC toolchain for cross compiling.")
 set(LIBUNWIND_SYSROOT "" CACHE PATH "Sysroot for cross compiling.")
+set(LIBUNWIND_TEST_LINKER_FLAGS "" CACHE STRING
+"Additional linker flags for test programs.")
+set(LIBUNWIND_TEST_COMPILER_FLAGS "" CACHE STRING
+"Additional compiler flags for test programs.")
 
 if (NOT LIBUNWIND_ENABLE_SHARED AND NOT LIBUNWIND_ENABLE_STATIC)
   message(FATAL_ERROR "libunwind must be built as either a shared or static 
library.")


Index: libunwind/trunk/test/lit.site.cfg.in
===
--- libunwind/trunk/test/lit.site.cfg.in
+++ libunwind/trunk/test/lit.site.cfg.in
@@ -12,6 +12,8 @@
 config.use_sanitizer= "@LLVM_USE_SANITIZER@"
 config.enable_32bit = "@LIBUNWIND_BUILD_32_BITS@"
 config.target_info  = "@LIBUNWIND_TARGET_INFO@"
+config.test_linker_flags= "@LIBUNWIND_TEST_LINKER_FLAGS@"
+config.test_compiler_flags  = "@LIBUNWIND_TEST_COMPILER_FLAGS@"
 config.executor = "@LIBUNWIND_EXECUTOR@"
 config.libunwind_shared = "@LIBUNWIND_ENABLE_SHARED@"
 config.enable_shared= "@LIBCXX_ENABLE_SHARED@"
Index: libunwind/trunk/CMakeLists.txt
===
--- libunwind/trunk/CMakeLists.txt
+++ libunwind/trunk/CMakeLists.txt
@@ -139,6 +139,10 @@
 set(LIBUNWIND_TARGET_TRIPLE "" CACHE STRING "Target triple for cross compiling.")
 set(LIBUNWIND_GCC_TOOLCHAIN "" CACHE PATH "GCC toolchain for cross compiling.")
 set(LIBUNWIND_SYSROOT "" CACHE PATH "Sysroot for cross compiling.")
+set(LIBUNWIND_TEST_LINKER_FLAGS "" CACHE STRING
+"Additional linker flags for test programs.")
+set(LIBUNWIND_TEST_COMPILER_FLAGS "" CACHE STRING
+"Additional compiler flags for test programs.")
 
 if (NOT LIBUNWIND_ENABLE_SHARED AND NOT LIBUNWIND_ENABLE_STATIC)
   message(FATAL_ERROR "libunwind must be built as either a shared or static library.")
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[libunwind] r326223 - [libunwind] Permit additional compiler and linker flags to be passed to tests.

2018-02-27 Thread John Baldwin via cfe-commits
Author: jhb
Date: Tue Feb 27 10:40:04 2018
New Revision: 326223

URL: http://llvm.org/viewvc/llvm-project?rev=326223&view=rev
Log:
[libunwind] Permit additional compiler and linker flags to be passed to tests.

Summary:
This is done via new LIBUNWIND_TEST_COMPILER_FLAGS and
LIBUNWIND_TEST_LINKER_FLAGS variables.

Reviewed By: sdardis

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

Modified:
libunwind/trunk/CMakeLists.txt
libunwind/trunk/test/lit.site.cfg.in

Modified: libunwind/trunk/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/libunwind/trunk/CMakeLists.txt?rev=326223&r1=326222&r2=326223&view=diff
==
--- libunwind/trunk/CMakeLists.txt (original)
+++ libunwind/trunk/CMakeLists.txt Tue Feb 27 10:40:04 2018
@@ -139,6 +139,10 @@ option(LIBUNWIND_INSTALL_LIBRARY "Instal
 set(LIBUNWIND_TARGET_TRIPLE "" CACHE STRING "Target triple for cross 
compiling.")
 set(LIBUNWIND_GCC_TOOLCHAIN "" CACHE PATH "GCC toolchain for cross compiling.")
 set(LIBUNWIND_SYSROOT "" CACHE PATH "Sysroot for cross compiling.")
+set(LIBUNWIND_TEST_LINKER_FLAGS "" CACHE STRING
+"Additional linker flags for test programs.")
+set(LIBUNWIND_TEST_COMPILER_FLAGS "" CACHE STRING
+"Additional compiler flags for test programs.")
 
 if (NOT LIBUNWIND_ENABLE_SHARED AND NOT LIBUNWIND_ENABLE_STATIC)
   message(FATAL_ERROR "libunwind must be built as either a shared or static 
library.")

Modified: libunwind/trunk/test/lit.site.cfg.in
URL: 
http://llvm.org/viewvc/llvm-project/libunwind/trunk/test/lit.site.cfg.in?rev=326223&r1=326222&r2=326223&view=diff
==
--- libunwind/trunk/test/lit.site.cfg.in (original)
+++ libunwind/trunk/test/lit.site.cfg.in Tue Feb 27 10:40:04 2018
@@ -12,6 +12,8 @@ config.enable_threads   = "@LIBU
 config.use_sanitizer= "@LLVM_USE_SANITIZER@"
 config.enable_32bit = "@LIBUNWIND_BUILD_32_BITS@"
 config.target_info  = "@LIBUNWIND_TARGET_INFO@"
+config.test_linker_flags= "@LIBUNWIND_TEST_LINKER_FLAGS@"
+config.test_compiler_flags  = "@LIBUNWIND_TEST_COMPILER_FLAGS@"
 config.executor = "@LIBUNWIND_EXECUTOR@"
 config.libunwind_shared = "@LIBUNWIND_ENABLE_SHARED@"
 config.enable_shared= "@LIBCXX_ENABLE_SHARED@"


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


[PATCH] D43775: add UUID to the acronyms list of objc property name checks

2018-02-27 Thread Yan Zhang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326222: add UUID to the acronyms list of objc property name 
checks (authored by Wizard, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D43775

Files:
  clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp


Index: clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp
@@ -50,6 +50,7 @@
 "FTP",
 "GIF",
 "GPS",
+"GUID",
 "HD",
 "HDR",
 "HTML",
@@ -87,6 +88,7 @@
 "UI",
 "URI",
 "URL",
+"UUID",
 "VC",
 "VOIP",
 "VPN",


Index: clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp
===
--- clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp
+++ clang-tools-extra/trunk/clang-tidy/objc/PropertyDeclarationCheck.cpp
@@ -50,6 +50,7 @@
 "FTP",
 "GIF",
 "GPS",
+"GUID",
 "HD",
 "HDR",
 "HTML",
@@ -87,6 +88,7 @@
 "UI",
 "URI",
 "URL",
+"UUID",
 "VC",
 "VOIP",
 "VPN",
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D43775: add UUID to the acronyms list of objc property name checks

2018-02-27 Thread Ben Hamilton via Phabricator via cfe-commits
benhamilton added a comment.

LGTM.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D43775



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


[PATCH] D43775: add UUID to the acronyms list of objc property name checks

2018-02-27 Thread Yan Zhang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rCTE326222: add UUID to the acronyms list of objc property 
name checks (authored by Wizard, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D43775?vs=136100&id=136102#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D43775

Files:
  clang-tidy/objc/PropertyDeclarationCheck.cpp


Index: clang-tidy/objc/PropertyDeclarationCheck.cpp
===
--- clang-tidy/objc/PropertyDeclarationCheck.cpp
+++ clang-tidy/objc/PropertyDeclarationCheck.cpp
@@ -50,6 +50,7 @@
 "FTP",
 "GIF",
 "GPS",
+"GUID",
 "HD",
 "HDR",
 "HTML",
@@ -87,6 +88,7 @@
 "UI",
 "URI",
 "URL",
+"UUID",
 "VC",
 "VOIP",
 "VPN",


Index: clang-tidy/objc/PropertyDeclarationCheck.cpp
===
--- clang-tidy/objc/PropertyDeclarationCheck.cpp
+++ clang-tidy/objc/PropertyDeclarationCheck.cpp
@@ -50,6 +50,7 @@
 "FTP",
 "GIF",
 "GPS",
+"GUID",
 "HD",
 "HDR",
 "HTML",
@@ -87,6 +88,7 @@
 "UI",
 "URI",
 "URL",
+"UUID",
 "VC",
 "VOIP",
 "VPN",
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   >