[PATCH] D45835: Add new driver mode for dumping compiler options

2018-05-27 Thread Hal Finkel via Phabricator via cfe-commits
hfinkel added inline comments.



Comment at: test/Frontend/compiler-options-dump.cpp:3
+// RUN: %clang_cc1 -compiler-options-dump -std=c++17 %s -o - | FileCheck %s 
--check-prefix=CXX17
+// RUN: %clang_cc1 -compiler-options-dump -std=c99 -ffast-math -x c %s -o - | 
FileCheck %s --check-prefix=C99
+

You don't need -ffast-math here I presume.



Comment at: test/Frontend/compiler-options-dump.cpp:15
+// CXX17: "extensions"
+// CXX17: "cxx_range_for" : true
+

cxx_range_for is both a feature and an extension?


https://reviews.llvm.org/D45835



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


[PATCH] D47419: [SemaDeclCXX] Allow inheriting constructor declaration that specify a cv-qualified type

2018-05-27 Thread Richard Smith - zygoloid via Phabricator via cfe-commits
rsmith added inline comments.



Comment at: lib/Sema/SemaDeclCXX.cpp:9690
+  CanQualType CanonicalDesiredBase = DesiredBase->getCanonicalTypeUnqualified()
+.getUnqualifiedType();
   for (auto  : Derived->bases()) {

How are we getting a qualified type here? Is this actually a bug in 
`getCanonicalTypeUnqualified`?


Repository:
  rC Clang

https://reviews.llvm.org/D47419



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


[PATCH] D47417: [analyzer] Add missing state transition in IteratorChecker

2018-05-27 Thread Henry Wong via Phabricator via cfe-commits
MTC added inline comments.



Comment at: lib/StaticAnalyzer/Checkers/IteratorChecker.cpp:399
+
+  C.addTransition(State);
 }

I have two questions may need @NoQ or @xazax.hun who is more familiar with the 
analyzer engine help to answer.

  - `State` may not change at all, do we need a check here like [[ 
https://github.com/llvm-mirror/clang/blob/master/lib/StaticAnalyzer/Checkers/ArrayBoundCheckerV2.cpp#L227
 | if (state != originalState) ]]
  - A more basic problem is that do we need `originalState = State` trick. It 
seems that `addTransitionImpl()` has a check about same state transition, see 
[[ 
https://github.com/llvm-mirror/clang/blob/master/include/clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h#L339
 | addTransitionImp() ]].

Thanks in advance!





Repository:
  rC Clang

https://reviews.llvm.org/D47417



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


[PATCH] D47435: Add __builtin_signbit semantic checking

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



Comment at: test/Sema/builtins.c:228
 // expected-note {{change size argument to 
be the size of the destination}}
-   
+
 __builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 
0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call 
appears to be size of the source; expected the size of the destination}} \

I'll revert this sneaky whitespace either as part of the commit, or as an 
updated patch if one is required.


Repository:
  rC Clang

https://reviews.llvm.org/D47435



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


[PATCH] D47435: Add __builtin_signbit semantic checking

2018-05-27 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman created this revision.
aaron.ballman added reviewers: rengolin, chatur01, rsmith.
aaron.ballman added inline comments.



Comment at: test/Sema/builtins.c:228
 // expected-note {{change size argument to 
be the size of the destination}}
-   
+
 __builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 
0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call 
appears to be size of the source; expected the size of the destination}} \

I'll revert this sneaky whitespace either as part of the commit, or as an 
updated patch if one is required.


r242675 changed the signature for the signbit builtin but did not introduce 
proper semantic checking to ensure the arguments are as-expected. This lead to 
regressions like the one reported in PR28172 where codegen would crash. This 
patch addresses this by properly grouping the signbit builtins along with the 
other fp classification builtins.


Repository:
  rC Clang

https://reviews.llvm.org/D47435

Files:
  lib/Sema/SemaChecking.cpp
  test/Sema/builtins.c


Index: test/Sema/builtins.c
===
--- test/Sema/builtins.c
+++ test/Sema/builtins.c
@@ -225,7 +225,7 @@
 
 strlcat(buf, b, sizeof(b)); // expected-warning {{size argument in 
'strlcat' call appears to be size of the source; expected the size of the 
destination}} \
 // expected-note {{change size argument to 
be the size of the destination}}
-   
+
 __builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 
0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call 
appears to be size of the source; expected the size of the destination}} \

// expected-note {{change size argument to be the size of the destination}} 
\

   // expected-warning {{'__builtin___strlcat_chk' will always overflow 
destination buffer}}
@@ -253,3 +253,17 @@
   __sync_fetch_and_add(ptr, 1); // expected-error{{address argument to atomic 
builtin cannot be const-qualified ('const int *' invalid)}}
   __atomic_fetch_add(ptr, 1, 0);  // expected-error {{address argument to 
atomic operation must be a pointer to non-const type ('const int *' invalid)}}
 }
+
+void test22(void) {
+  (void)__builtin_signbit(); // expected-error{{too few arguments to function 
call, expected 1, have 0}}
+  (void)__builtin_signbit(1.0, 2.0, 3.0); // expected-error{{too many 
arguments to function call, expected 1, have 3}}
+  (void)__builtin_signbit(1); // expected-error {{floating point 
classification requires argument of floating point type (passed in 'int')}}
+
+  (void)__builtin_signbitf(); // expected-error{{too few arguments to function 
call, expected 1, have 0}}
+  (void)__builtin_signbitf(1.0, 2.0, 3.0); // expected-error{{too many 
arguments to function call, expected 1, have 3}}
+  (void)__builtin_signbitf(1);
+
+  (void)__builtin_signbitl(); // expected-error{{too few arguments to function 
call, expected 1, have 0}}
+  (void)__builtin_signbitl(1.0, 2.0, 3.0); // expected-error{{too many 
arguments to function call, expected 1, have 3}}
+  (void)__builtin_signbitl(1);
+}
Index: lib/Sema/SemaChecking.cpp
===
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -919,6 +919,9 @@
   case Builtin::BI__builtin_isinf_sign:
   case Builtin::BI__builtin_isnan:
   case Builtin::BI__builtin_isnormal:
+  case Builtin::BI__builtin_signbit:
+  case Builtin::BI__builtin_signbitf:
+  case Builtin::BI__builtin_signbitl:
 if (SemaBuiltinFPClassification(TheCall, 1))
   return ExprError();
 break;


Index: test/Sema/builtins.c
===
--- test/Sema/builtins.c
+++ test/Sema/builtins.c
@@ -225,7 +225,7 @@
 
 strlcat(buf, b, sizeof(b)); // expected-warning {{size argument in 'strlcat' call appears to be size of the source; expected the size of the destination}} \
 // expected-note {{change size argument to be the size of the destination}}
-
+
 __builtin___strlcat_chk(buf, b, sizeof(b), __builtin_object_size(buf, 0)); // expected-warning {{size argument in '__builtin___strlcat_chk' call appears to be size of the source; expected the size of the destination}} \
// expected-note {{change size argument to be the size of the destination}} \
    // expected-warning {{'__builtin___strlcat_chk' will always overflow destination buffer}}
@@ -253,3 +253,17 @@
   

[PATCH] D45532: [StaticAnalyzer] Checker to find uninitialized fields after a constructor call

2018-05-27 Thread Umann Kristóf via Phabricator via cfe-commits
Szelethus marked 9 inline comments as done.
Szelethus added a comment.

Thanks again for taking a look :)




Comment at: lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp:359-372
+  // Checking bases.
+  const auto *CXXRD = dyn_cast(RD);
+  if (!CXXRD)
+return ContainsUninitField;
+
+  for (const CXXBaseSpecifier BaseSpec : CXXRD->bases()) {
+const auto *Base = BaseSpec.getType()->getAsCXXRecordDecl();

NoQ wrote:
> Szelethus wrote:
> > NoQ wrote:
> > > Are there many warnings that will be caused by this but won't be caused 
> > > by conducting the check for the constructor-within-constructor that's 
> > > currently disabled? Not sure - is it even syntactically possible to not 
> > > initialize the base class?
> > I'm not a 100% sure what you mean. Can you clarify?
> > >Not sure - is it even syntactically possible to not initialize the base 
> > >class?
> > If I understand the question correctly, no, as far as I know.
> You have a check for `isCalledByConstructor()` in order to skip base class 
> constructors but then you check them manually. That's a lot of code, but it 
> seems that the same result could have been achieved by simply skipping the 
> descent into the base class.
> 
> Same question for class-type fields, actually.
>Same question for class-type fields, actually.

My problem with that approach is that the same uninitialized field could've 
been emitted multiple times in different warnings. From an earlier conversation 
(assume that its run in pedantic mode):

>For this code snippet:
>
> ```
>struct A {
>   struct B {
>  int x, y;
>  
>  B() {}
>   } b;
>   int w;
>
>   A() {
>  b = B();
>   }
>};
>```
>the warning message after a call to `A::A()` would be "3 uninitialized 
>fields[...]", and for `B::B()` inside `A`s constructor would be "2 
>uninitialized fields[...]", so it wouldn't be filtered out.

In my opinion, if `A` contains a field of type `B`, it should be the 
responsibility of `A`'s constructors to initialize those fields properly.
>You have a check for isCalledByConstructor() in order to skip base class 
>constructors but then you check them manually. That's a lot of code, but it 
>seems that the same result could have been achieved by simply skipping the 
>descent into the base class.
I also believe that a constructor "should be held responsible" for the 
initialization of the inherited data members. However, in the case of base 
classes, uniqueing isn't an issue, as in this case:
```
struct B {
  int a;
  B() {}
};

struct D : public B {
  int b;
  D() {}
};
```
a call to `D::D()` would not check the inherited member (`a`), if I didn't 
implement it explicitly. That also means that if `isCalledByConstructor` was 
refactored to not filter out base classes, we would get two warning each with a 
single note, reporting `b` and `a` respectively. (I haven't actually checked 
it, but its a reasonable assumption)

Actually, I'm not 100% sure which approach is better: a warning for each base, 
or one warning for the object, bases included. I personally think one warning 
per object results in the best user experience.

I like both ideas, but I think if we'd come to the conclusion that a warning 
per base should be the way to go, it should definitely be implemented in a 
followup patch, as `isCalledByConstructor` is already in line for some major 
refactoring.

What do you think? :)



Comment at: lib/StaticAnalyzer/Checkers/UninitializedObjectChecker.cpp:405-406
+  SVal DerefdV = StoreMgr.getBinding(S, V.castAs());
+  while (Optional L = DerefdV.getAs())
+DerefdV = StoreMgr.getBinding(S, *L);
+

NoQ wrote:
> Szelethus wrote:
> > NoQ wrote:
> > > Is this loop guaranteed to terminate? Is something like `void *v; v = 
> > > ` possible?
> > > 
> > > I think this loop should unwrap the AST type on every iteration and 
> > > dereference the pointer accordingly.
> > > 
> > > In general, i believe that every symbolic pointer dereference should be 
> > > made with awareness of the type of the object we're trying to retrieve. 
> > > Which is an optional argument for `State->getSVal(R, ...)`, but it seems 
> > > that it should be made mandatory because in a lot of cases omitting it 
> > > causes problems.
> > > Is this loop guaranteed to terminate? Is something like void *v; v =  
> > > possible?
> > I looked this up, and I am confident that it is not possible for a pointer 
> > to point to itself. Only a `void**` object may point to a `void*`. The loop 
> > terminates even if you do something evil like `v = 
> > reinterpret_cast();` (I have tried this with `int`s).
> > 
> > >I think this loop should unwrap the AST type on every iteration and 
> > >dereference the pointer accordingly.
> > >
> > >In general, i believe that every symbolic pointer dereference should be 
> > >made with awareness of the type of the object we're trying to retrieve. 
> > >Which is an optional argument for 

[PATCH] D47108: [CodeGenCXX] Add -fforce-emit-vtables

2018-05-27 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 148764.
Prazek added a comment.

small update


Repository:
  rL LLVM

https://reviews.llvm.org/D47108

Files:
  clang/docs/ClangCommandLineReference.rst
  clang/docs/ReleaseNotes.rst
  clang/docs/UsersManual.rst
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CodeGenCXX/vtable-available-externally.cpp

Index: clang/test/CodeGenCXX/vtable-available-externally.cpp
===
--- clang/test/CodeGenCXX/vtable-available-externally.cpp
+++ clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables -fstrict-vtable-pointers
 // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
@@ -13,10 +14,13 @@
 // RUN: FileCheck --check-prefix=CHECK-TEST15 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST16 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST17 %s < %t.opt
+// RUN: FileCheck --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
+
 
 #include 
 
 // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
 namespace Test1 {
 
 struct A {
@@ -213,14 +217,16 @@
 
 // because A's key function is defined here, vtable is generated in this TU
 // CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr.
 // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
@@ -237,14 +243,17 @@
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally.
 // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
 // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+
 struct E : A {};
 
 void g(A& a) {
@@ -298,11 +307,13 @@
 namespace Test12 {
 
 // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual ~A() {}
 };
 // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
 };
@@ -319,6 +330,9 @@
 
 // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
 // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant
+
 struct A {
   virtual ~A();
 };
@@ -371,6 +385,8 @@
 // generate available_externally vtable for it.
 // CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
 // CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally
 
 struct S {
   __attribute__((visibility("hidden"))) virtual void doStuff();
@@ -395,6 +411,10 @@
 // This test checks if we emit vtables opportunistically.
 // CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally
 // CHECK-TEST17-DAG: @_ZTVN6Test171BE = external
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD1Ev(
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(
 
 struct A {
   virtual void key();
@@ -418,3 +438,27 @@
 }
 
 } // 

[PATCH] D47419: [SemaDeclCXX] Allow inheriting constructor declaration that specify a cv-qualified type

2018-05-27 Thread Rustam Abdullaev via Phabricator via cfe-commits
rustam added a comment.

I believe this fixed the bug #37600 



Repository:
  rC Clang

https://reviews.llvm.org/D47419



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


[PATCH] D47108: [CodeGenCXX] Add -fforce-emit-vtables

2018-05-27 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 148762.
Prazek added a comment.

Fixed missing vtable commponents


Repository:
  rL LLVM

https://reviews.llvm.org/D47108

Files:
  clang/docs/ClangCommandLineReference.rst
  clang/docs/ReleaseNotes.rst
  clang/docs/UsersManual.rst
  clang/include/clang/Basic/LangOptions.def
  clang/include/clang/Driver/Options.td
  clang/include/clang/Frontend/CodeGenOptions.def
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Driver/ToolChains/Clang.cpp
  clang/lib/Frontend/CompilerInvocation.cpp
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CodeGenCXX/vtable-available-externally.cpp

Index: clang/test/CodeGenCXX/vtable-available-externally.cpp
===
--- clang/test/CodeGenCXX/vtable-available-externally.cpp
+++ clang/test/CodeGenCXX/vtable-available-externally.cpp
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -emit-llvm -o %t
 // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.opt
+// RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -std=c++98 -O2 -disable-llvm-passes -emit-llvm -o %t.vtable -fforce-emit-vtables -fstrict-vtable-pointers
 // RUN: FileCheck --check-prefix=CHECK-TEST1 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST2 %s < %t
 // RUN: FileCheck --check-prefix=CHECK-TEST5 %s < %t
@@ -13,10 +14,13 @@
 // RUN: FileCheck --check-prefix=CHECK-TEST15 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST16 %s < %t.opt
 // RUN: FileCheck --check-prefix=CHECK-TEST17 %s < %t.opt
+// RUN: FileCheck --check-prefix=CHECK-FORCE-EMIT %s < %t.vtable
+
 
 #include 
 
 // CHECK-TEST1: @_ZTVN5Test11AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN5Test11AE = available_externally unnamed_addr constant
 namespace Test1 {
 
 struct A {
@@ -213,14 +217,16 @@
 
 // because A's key function is defined here, vtable is generated in this TU
 // CHECK-TEST10-DAG: @_ZTVN6Test101AE = unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101AE = unnamed_addr constant
 struct A {
   virtual void foo();
   virtual void bar();
 };
 void A::foo() {}
 
 // Because key function is inline we will generate vtable as linkonce_odr.
 // CHECK-TEST10-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101DE = linkonce_odr unnamed_addr constant
 struct D : A {
   void bar();
 };
@@ -237,14 +243,17 @@
 // can't guarantee that we will be able to refer to bar from name
 // so (at the moment) we can't emit vtable available_externally.
 // CHECK-TEST10-DAG: @_ZTVN6Test101CE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101CE = available_externally unnamed_addr constant
 struct C : A {
   void bar() {}   // defined in body - not key function
   virtual inline void gar();  // inline in body - not key function
   virtual void car();
 };
 
 // no key function, vtable will be generated everywhere it will be used
 // CHECK-TEST10-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test101EE = linkonce_odr unnamed_addr constant
+
 struct E : A {};
 
 void g(A& a) {
@@ -298,11 +307,13 @@
 namespace Test12 {
 
 // CHECK-TEST12: @_ZTVN6Test121AE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121AE = available_externally unnamed_addr constant
 struct A {
   virtual void foo();
   virtual ~A() {}
 };
 // CHECK-TEST12: @_ZTVN6Test121BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test121BE = available_externally unnamed_addr constant
 struct B : A {
   void foo();
 };
@@ -319,6 +330,9 @@
 
 // CHECK-TEST13-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
 // CHECK-TEST13-DAG: @_ZTVN6Test131BE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131AE = available_externally unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test131BE = available_externally unnamed_addr constant
+
 struct A {
   virtual ~A();
 };
@@ -371,6 +385,8 @@
 // generate available_externally vtable for it.
 // CHECK-TEST16-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
 // CHECK-TEST16-DAG: @_ZTVN6Test162S2E = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test161SE = external unnamed_addr constant
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test162S2E = available_externally
 
 struct S {
   __attribute__((visibility("hidden"))) virtual void doStuff();
@@ -395,6 +411,10 @@
 // This test checks if we emit vtables opportunistically.
 // CHECK-TEST17-DAG: @_ZTVN6Test171AE = available_externally
 // CHECK-TEST17-DAG: @_ZTVN6Test171BE = external
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171AE = available_externally
+// CHECK-FORCE-EMIT-DAG: @_ZTVN6Test171BE = available_externally
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD1Ev(
+// CHECK-FORCE-EMIT-DAG: define linkonce_odr void @_ZN6Test171BD0Ev(
 
 struct A {
   virtual void key();
@@ -418,3 +438,27 

[PATCH] D46112: Allow _Atomic to be specified on incomplete types

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

In https://reviews.llvm.org/D46112#1098243, @rsmith wrote:

> In https://reviews.llvm.org/D46112#1096893, @aaron.ballman wrote:
>
> > In https://reviews.llvm.org/D46112#1091981, @efriedma wrote:
> >
> > > Also needs some test coverage for atomic operations which aren't calls, 
> > > like "typedef struct S S; void f(_Atomic S *s, _Atomic S *s2) { *s = *s2; 
> > > };".
> >
> >
> > Thank you for pointing this out -- that uncovered an issue where we were 
> > not properly diagnosing the types as being incomplete. I've added a new 
> > test case and rolled the contents of Sema\atomic-type.cpp (which I added in 
> > an earlier patch) into SemaCXX\atomic-type.cpp (which already existed and I 
> > missed it).
>
>
> I don't think this has sufficiently addressed the comment. Specifically, for 
> a case like:
>
>   struct NotTriviallyCopyable { NotTriviallyCopyable(const 
> NotTriviallyCopyable&); };
>   void f(_Atomic NotTriviallyCopyable *p) { *p = *p; }
>
>
> ... we should reject the assignment, because it would perform an atomic 
> operation on a non-trivially-copyable type. It would probably suffice to 
> check the places where we form an `AtomicToNonAtomic` or `NonAtomicToAtomic` 
> conversion.
>
> In passing, I noticed that this crashes Clang (because we fail to create an 
> lvalue-to-rvalue conversion for `x`):
>
>   struct X {};  
>   void f(_Atomic X *p, X x) { *p = x; }
>
>
> This will likely get in the way of your test cases unless you fix it :)


It only gets in the way for C++ whereas my primary concern for this patch is C. 
I tried spending a few hours on this today and got nowhere -- we have a lot of 
FIXME comments surrounding atomic type qualifiers in C++. I've run out of time 
to be able to work on this patch and may have to abandon it. I'd hate to lose 
the forward progress already made, so I'm wondering if the C bits are 
sufficiently baked that even more FIXMEs around atomics in C++ would suffice?


https://reviews.llvm.org/D46112



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


[PATCH] D46112: Allow _Atomic to be specified on incomplete types

2018-05-27 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman updated this revision to Diff 148753.
aaron.ballman marked 4 inline comments as done.
aaron.ballman added a comment.

Corrected some of the review comments.


https://reviews.llvm.org/D46112

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/AST/Type.cpp
  lib/Sema/SemaChecking.cpp
  lib/Sema/SemaType.cpp
  test/CXX/stmt.stmt/stmt.iter/stmt.ranged/p1.cpp
  test/CodeGen/c11atomics.c
  test/Sema/atomic-type.c
  test/SemaCXX/atomic-type.cpp
  test/SemaObjC/arc.m

Index: test/SemaObjC/arc.m
===
--- test/SemaObjC/arc.m
+++ test/SemaObjC/arc.m
@@ -410,7 +410,7 @@
   [v test16_6: 0];
 }
 
-@class Test17; // expected-note 2{{forward declaration of class here}}
+@class Test17; // expected-note 3{{forward declaration of class here}}
 @protocol Test17p
 - (void) test17;
 + (void) test17;
Index: test/SemaCXX/atomic-type.cpp
===
--- test/SemaCXX/atomic-type.cpp
+++ test/SemaCXX/atomic-type.cpp
@@ -94,3 +94,15 @@
 bool PR21836(_Atomic(int) *x) {
 return *x;
 }
+
+struct T;
+
+void f(_Atomic T *t);
+
+struct T { int a, b; };
+
+void f(_Atomic T *t) {
+  T t2;
+  (void)__atomic_load(t, , 5); // expected-error {{address argument to atomic operation must be a pointer to a trivially-copyable type ('_Atomic(T) *' invalid)}}
+  (void)__c11_atomic_load(t, 5);
+}
Index: test/Sema/atomic-type.c
===
--- test/Sema/atomic-type.c
+++ test/Sema/atomic-type.c
@@ -16,7 +16,23 @@
 extern _Atomic(int (*)(int(*)[10], int(*)[10])) mergetest;
 
 _Atomic(int()) error1; // expected-error {{_Atomic cannot be applied to function type}}
-_Atomic(struct ErrorS) error2; // expected-error {{_Atomic cannot be applied to incomplete type}} expected-note {{forward declaration}}
+_Atomic(struct ErrorS) error2; // expected-error {{tentative definition has type '_Atomic(struct ErrorS)' that is never completed}} \
+   // expected-note {{forward declaration of 'struct ErrorS'}}
 _Atomic(int[10]) error3; // expected-error {{_Atomic cannot be applied to array type}}
 _Atomic(const int) error4; // expected-error {{_Atomic cannot be applied to qualified type}}
 _Atomic(_Atomic(int)) error5; // expected-error {{_Atomic cannot be applied to atomic type}}
+
+void g(_Atomic void *ptr);
+void h(_Atomic struct Incomplete *ptr); // expected-warning {{declaration of 'struct Incomplete' will not be visible outside of this function}}
+
+void test_atomic_void_ptr(_Atomic void *addr) {
+  int i;
+  (void)__atomic_load(addr, , 5); // expected-error {{address argument to atomic operation must be a pointer to a trivially-copyable type ('_Atomic(void) *' invalid)}}
+  (void)__c11_atomic_load(addr, 5); // expected-error {{invalid use of incomplete type 'void'}}
+  _Static_assert(__atomic_is_lock_free(1, addr), "");
+}
+
+typedef struct S S; // expected-note {{forward declaration of 'struct S'}}
+void test_atomic_incomplete_struct_assignment(_Atomic S *s, _Atomic S *s2) {
+  *s = *s2; // expected-error {{incomplete type '_Atomic(S)' is not assignable}}
+}
Index: test/CodeGen/c11atomics.c
===
--- test/CodeGen/c11atomics.c
+++ test/CodeGen/c11atomics.c
@@ -61,7 +61,7 @@
   // we have to generate an atomic add, which returns the old value, and then a
   // non-atomic add.
   // CHECK: atomicrmw add i32* @i, i32 1 seq_cst
-  // CHECK: add i32 
+  // CHECK: add i32
   ++i;
   // CHECK: atomicrmw add i64* @l, i64 1 seq_cst
   // CHECK: add i64
@@ -475,6 +475,25 @@
   return __c11_atomic_compare_exchange_strong(addr, desired, *new, 5, 5);
 }
 
+int test_atomic_void_ptr(_Atomic void *addr) {
+  // CHECK-LABEL: @test_atomic_void_ptr(
+  // CHECK:   [[ADDR_ARG:%.*]] = alloca { i8, [1 x i8] }*, align 4
+  // CHECK:   [[ATOMIC_RES:%.*]] = alloca i32, align 4
+  // CHECK:   store { i8, [1 x i8] }* %addr, { i8, [1 x i8] }** [[ADDR_ARG]], align 4
+  // CHECK:   [[ADDR_LOCK_FREE_VP:%.*]] = load { i8, [1 x i8] }*, { i8, [1 x i8] }** [[ADDR_ARG]], align 4
+  // CHECK:   [[ADDR_LOCK_FREE:%.*]] = bitcast { i8, [1 x i8] }* [[ADDR_LOCK_FREE_VP]] to i8*
+  // CHECK:   call arm_aapcscc i32 @__atomic_is_lock_free(i32 1, i8* [[ADDR_LOCK_FREE]])
+  // CHECK:   [[ADDR:%.*]] = load { i8, [1 x i8] }*, { i8, [1 x i8] }** [[ADDR_ARG]], align 4
+  // CHECK:   [[CAST1:%.*]] = bitcast { i8, [1 x i8] }* [[ADDR]] to i32*
+  // CHECK:   [[CAST2:%.*]] = bitcast i32* [[CAST1]] to i8*
+  // CHECK:   [[CALL:%.*]] = call arm_aapcscc i32 @__atomic_load_4(i8* [[CAST2]], i32 5)
+  // CHECK:   store i32 [[CALL]], i32* [[ATOMIC_RES]], align 4
+  // CHECK:   [[RES:%.*]] = load i32, i32* [[ATOMIC_RES]], align 4
+  // CHECK:   ret i32 [[RES]]
+  (void)__atomic_is_lock_free(1, addr);
+  return (int)__c11_atomic_load((_Atomic int *)addr, 5);
+}
+
 struct Empty {};
 
 struct Empty test_empty_struct_load(_Atomic(struct Empty)* 

[PATCH] D45835: Add new driver mode for dumping compiler options

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

Ping.


https://reviews.llvm.org/D45835



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


[PATCH] D47299: [CodeGenCXX] Emit strip.invariant.group with -fstrict-vtable-pointers

2018-05-27 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 148746.
Prazek marked 3 inline comments as done.
Prazek added a comment.

one more test


Repository:
  rL LLVM

https://reviews.llvm.org/D47299

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/CodeGenCXX/strict-vtable-pointers.cpp

Index: clang/test/CodeGenCXX/strict-vtable-pointers.cpp
===
--- clang/test/CodeGenCXX/strict-vtable-pointers.cpp
+++ clang/test/CodeGenCXX/strict-vtable-pointers.cpp
@@ -5,7 +5,8 @@
 // RUN: FileCheck --check-prefix=CHECK-LINK-REQ %s < %t.ll
 
 typedef __typeof__(sizeof(0)) size_t;
-void *operator new(size_t, void*) throw();
+void *operator new(size_t, void *) throw();
+using uintptr_t = unsigned long long;
 
 struct NotTrivialDtor {
   ~NotTrivialDtor();
@@ -17,7 +18,7 @@
 };
 
 struct DynamicDerived : DynamicBase1 {
-  void foo();
+  void foo() override;
 };
 
 struct DynamicBase2 {
@@ -28,8 +29,8 @@
 };
 
 struct DynamicDerivedMultiple : DynamicBase1, DynamicBase2 {
-  virtual void foo();
-  virtual void bar();
+  void foo() override;
+  void bar() override;
 };
 
 struct StaticBase {
@@ -47,9 +48,8 @@
 struct DynamicFromVirtualStatic2 : virtual StaticBase {
 };
 
-struct DynamicFrom2Virtuals :
-DynamicFromVirtualStatic1,
-DynamicFromVirtualStatic2 {
+struct DynamicFrom2Virtuals : DynamicFromVirtualStatic1,
+  DynamicFromVirtualStatic2 {
 };
 
 // CHECK-NEW-LABEL: define void @_Z12LocalObjectsv()
@@ -89,7 +89,6 @@
 // CHECK-CTORS: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-CTORS-LABEL: {{^}}}
 
-
 // CHECK-NEW-LABEL: define void @_Z9Pointers1v()
 // CHECK-NEW-NOT: @llvm.launder.invariant.group.p0i8(
 // CHECK-NEW-LABEL: call void @_ZN12DynamicBase1C1Ev(
@@ -134,7 +133,6 @@
 // CHECK-CTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-CTORS-LABEL: {{^}}}
 
-
 struct DynamicDerived;
 
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedC2Ev(
@@ -164,14 +162,12 @@
 // CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev(
 // CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8
 
-
 // CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
 // CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 0, i32 2) {{.*}} %[[THIS10]]
 // CHECK-CTORS: %[[THIS11:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i8*
 // CHECK-CTORS: %[[THIS_ADD:.*]] = getelementptr inbounds i8, i8* %[[THIS11]], i64 16
 // CHECK-CTORS: %[[THIS12:.*]]  = bitcast i8* %[[THIS_ADD]] to i32 (...)***
 
-
 // CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 1, i32 2) {{.*}} %[[THIS12]]
 // CHECK-CTORS-LABEL: {{^}}}
 
@@ -182,9 +178,10 @@
 
 struct A {
   virtual void foo();
+  int m;
 };
 struct B : A {
-  virtual void foo();
+  void foo() override;
 };
 
 union U {
@@ -209,7 +206,7 @@
   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: call void @_Z2g2P1A(%struct.A*
   g2(>b);
-  // CHECK-NEW: call void @_Z9changeToAP1U(%union.U* 
+  // CHECK-NEW: call void @_Z9changeToAP1U(%union.U*
   changeToA(u);
   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // call void @_Z2g2P1A(%struct.A* %a)
@@ -294,21 +291,287 @@
   take(u.v3);
 }
 
+// CHECK-NEW-LABEL: define void @_Z7comparev()
+void compare() {
+  A *a = new A;
+  a->foo();
+  // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
+  A *b = new (a) B;
+
+  // CHECK-NEW: %[[a:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+  // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A*
+  // CHECK-NEW: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+  // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A*
+  // CHECK-NEW: %cmp = icmp eq %struct.A* %[[a2]], %[[b2]]
+  if (a == b)
+b->foo();
+}
+
+// CHECK-NEW-LABEL: compare2
+bool compare2(A *a, A *a2) {
+  // CHECK-NEW: %[[a:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+  // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A*
+  // CHECK-NEW: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+  // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A*
+  // CHECK-NEW: %cmp = icmp ult %struct.A* %[[a2]], %[[b2]]
+  return a < a2;
+}
+// CHECK-NEW-LABEL: compareIntPointers
+bool compareIntPointers(int *a, int *b) {
+  // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group
+  return a == b;
+}
+
+struct HoldingOtherVirtuals {
+  B b;
+};
+
+// There is no need to add barriers for comparision of pointer to classes
+// that are not dynamic.
+// CHECK-NEW-LABEL: compare5
+bool compare5(HoldingOtherVirtuals *a, HoldingOtherVirtuals *b) {
+  // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group
+  return a == b;
+}
+// CHECK-NEW-LABEL: compareNull
+bool compareNull(A *a) {
+  // CHECK-NEW-NOT: call i8* @llvm.strip.invariant.group
+
+  if (a != nullptr)
+return 

[PATCH] D47299: [CodeGenCXX] Emit strip.invariant.group with -fstrict-vtable-pointers

2018-05-27 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek updated this revision to Diff 148745.
Prazek added a comment.
Herald added a subscriber: hiraditya.

  Added launder when going from possiblyNotDynamic to possiblyDynamic
  emitting strip for pointer -> int only if poitner is possiblyDynamic


Repository:
  rL LLVM

https://reviews.llvm.org/D47299

Files:
  clang/include/clang/AST/DeclCXX.h
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprScalar.cpp
  clang/test/CodeGenCXX/strict-vtable-pointers.cpp
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
===
--- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -1205,6 +1205,7 @@
   if (StrippedInvariantGroupsArg == StrippedArg)
 return nullptr;
 
+  return nullptr;
   if (II.getIntrinsicID() == Intrinsic::launder_invariant_group)
 return cast(IC.Builder.CreateLaunderInvariantGroup(StrippedInvariantGroupsArg));
   if (II.getIntrinsicID() == Intrinsic::strip_invariant_group)
Index: clang/test/CodeGenCXX/strict-vtable-pointers.cpp
===
--- clang/test/CodeGenCXX/strict-vtable-pointers.cpp
+++ clang/test/CodeGenCXX/strict-vtable-pointers.cpp
@@ -5,7 +5,8 @@
 // RUN: FileCheck --check-prefix=CHECK-LINK-REQ %s < %t.ll
 
 typedef __typeof__(sizeof(0)) size_t;
-void *operator new(size_t, void*) throw();
+void *operator new(size_t, void *) throw();
+using uintptr_t = unsigned long long;
 
 struct NotTrivialDtor {
   ~NotTrivialDtor();
@@ -17,7 +18,7 @@
 };
 
 struct DynamicDerived : DynamicBase1 {
-  void foo();
+  void foo() override;
 };
 
 struct DynamicBase2 {
@@ -28,8 +29,8 @@
 };
 
 struct DynamicDerivedMultiple : DynamicBase1, DynamicBase2 {
-  virtual void foo();
-  virtual void bar();
+  void foo() override;
+  void bar() override;
 };
 
 struct StaticBase {
@@ -47,9 +48,8 @@
 struct DynamicFromVirtualStatic2 : virtual StaticBase {
 };
 
-struct DynamicFrom2Virtuals :
-DynamicFromVirtualStatic1,
-DynamicFromVirtualStatic2 {
+struct DynamicFrom2Virtuals : DynamicFromVirtualStatic1,
+  DynamicFromVirtualStatic2 {
 };
 
 // CHECK-NEW-LABEL: define void @_Z12LocalObjectsv()
@@ -89,7 +89,6 @@
 // CHECK-CTORS: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-CTORS-LABEL: {{^}}}
 
-
 // CHECK-NEW-LABEL: define void @_Z9Pointers1v()
 // CHECK-NEW-NOT: @llvm.launder.invariant.group.p0i8(
 // CHECK-NEW-LABEL: call void @_ZN12DynamicBase1C1Ev(
@@ -134,7 +133,6 @@
 // CHECK-CTORS-NOT: call i8* @llvm.launder.invariant.group.p0i8(
 // CHECK-CTORS-LABEL: {{^}}}
 
-
 struct DynamicDerived;
 
 // CHECK-CTORS-LABEL: define linkonce_odr void @_ZN14DynamicDerivedC2Ev(
@@ -164,14 +162,12 @@
 // CHECK-CTORS: call void @_ZN12DynamicBase2C2Ev(
 // CHECK-CTORS-NOT: @llvm.launder.invariant.group.p0i8
 
-
 // CHECK-CTORS: %[[THIS10:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i32 (...)***
 // CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 0, i32 2) {{.*}} %[[THIS10]]
 // CHECK-CTORS: %[[THIS11:.*]] = bitcast %struct.DynamicDerivedMultiple* %[[THIS0]] to i8*
 // CHECK-CTORS: %[[THIS_ADD:.*]] = getelementptr inbounds i8, i8* %[[THIS11]], i64 16
 // CHECK-CTORS: %[[THIS12:.*]]  = bitcast i8* %[[THIS_ADD]] to i32 (...)***
 
-
 // CHECK-CTORS: store {{.*}} @_ZTV22DynamicDerivedMultiple, i32 0, inrange i32 1, i32 2) {{.*}} %[[THIS12]]
 // CHECK-CTORS-LABEL: {{^}}}
 
@@ -182,9 +178,10 @@
 
 struct A {
   virtual void foo();
+  int m;
 };
 struct B : A {
-  virtual void foo();
+  void foo() override;
 };
 
 union U {
@@ -209,7 +206,7 @@
   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // CHECK-NEW: call void @_Z2g2P1A(%struct.A*
   g2(>b);
-  // CHECK-NEW: call void @_Z9changeToAP1U(%union.U* 
+  // CHECK-NEW: call void @_Z9changeToAP1U(%union.U*
   changeToA(u);
   // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
   // call void @_Z2g2P1A(%struct.A* %a)
@@ -294,21 +291,283 @@
   take(u.v3);
 }
 
+// CHECK-NEW-LABEL: define void @_Z7comparev()
+void compare() {
+  A *a = new A;
+  a->foo();
+  // CHECK-NEW: call i8* @llvm.launder.invariant.group.p0i8(i8*
+  A *b = new (a) B;
+
+  // CHECK-NEW: %[[a:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+  // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A*
+  // CHECK-NEW: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+  // CHECK-NEW: %[[b2:.*]] = bitcast i8* %[[b]] to %struct.A*
+  // CHECK-NEW: %cmp = icmp eq %struct.A* %[[a2]], %[[b2]]
+  if (a == b)
+b->foo();
+}
+
+// CHECK-NEW-LABEL: compare2
+bool compare2(A *a, A *a2) {
+  // CHECK-NEW: %[[a:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+  // CHECK-NEW: %[[a2:.*]] = bitcast i8* %[[a]] to %struct.A*
+  // CHECK-NEW: %[[b:.*]] = call i8* @llvm.strip.invariant.group.p0i8(i8*
+  // CHECK-NEW: %[[b2:.*]] = 

[PATCH] D47419: [SemaDeclCXX] Allow inheriting constructor declaration that specify a cv-qualified type

2018-05-27 Thread S. B. Tam via Phabricator via cfe-commits
cpplearner created this revision.
cpplearner added a reviewer: rsmith.
Herald added a subscriber: cfe-commits.

This will allow the following code:

  struct base {};
  using cbase = const base;
  struct inherit : cbase {
  using cbase::cbase; // previously error: 'cbase' (aka 'const base') is 
not a direct base of 'inherit', cannot inherit constructors
  };

See 
https://stackoverflow.com/questions/50534219/inherit-from-const-type-passed-as-template-parameter


Repository:
  rC Clang

https://reviews.llvm.org/D47419

Files:
  lib/Sema/SemaDeclCXX.cpp
  test/CXX/special/class.inhctor/elsewhere.cpp


Index: test/CXX/special/class.inhctor/elsewhere.cpp
===
--- test/CXX/special/class.inhctor/elsewhere.cpp
+++ test/CXX/special/class.inhctor/elsewhere.cpp
@@ -62,3 +62,4 @@
   G(int &) : G(0) {}
 };
 G g(123);
+G g2(123);
Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -9686,7 +9686,8 @@
 QualType DesiredBase,
 bool ) {
   // Check whether the named type is a direct base class.
-  CanQualType CanonicalDesiredBase = 
DesiredBase->getCanonicalTypeUnqualified();
+  CanQualType CanonicalDesiredBase = DesiredBase->getCanonicalTypeUnqualified()
+.getUnqualifiedType();
   for (auto  : Derived->bases()) {
 CanQualType BaseType = Base.getType()->getCanonicalTypeUnqualified();
 if (CanonicalDesiredBase == BaseType)


Index: test/CXX/special/class.inhctor/elsewhere.cpp
===
--- test/CXX/special/class.inhctor/elsewhere.cpp
+++ test/CXX/special/class.inhctor/elsewhere.cpp
@@ -62,3 +62,4 @@
   G(int &) : G(0) {}
 };
 G g(123);
+G g2(123);
Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -9686,7 +9686,8 @@
 QualType DesiredBase,
 bool ) {
   // Check whether the named type is a direct base class.
-  CanQualType CanonicalDesiredBase = DesiredBase->getCanonicalTypeUnqualified();
+  CanQualType CanonicalDesiredBase = DesiredBase->getCanonicalTypeUnqualified()
+.getUnqualifiedType();
   for (auto  : Derived->bases()) {
 CanQualType BaseType = Base.getType()->getCanonicalTypeUnqualified();
 if (CanonicalDesiredBase == BaseType)
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r333352 - [DebugInfo] Fix typo. NFC

2018-05-27 Thread Fangrui Song via cfe-commits
Author: maskray
Date: Sun May 27 00:23:04 2018
New Revision: 52

URL: http://llvm.org/viewvc/llvm-project?rev=52=rev
Log:
[DebugInfo] Fix typo. NFC

Modified:
cfe/trunk/include/clang/Basic/DebugInfoOptions.h

Modified: cfe/trunk/include/clang/Basic/DebugInfoOptions.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DebugInfoOptions.h?rev=52=51=52=diff
==
--- cfe/trunk/include/clang/Basic/DebugInfoOptions.h (original)
+++ cfe/trunk/include/clang/Basic/DebugInfoOptions.h Sun May 27 00:23:04 2018
@@ -28,7 +28,7 @@ enum DebugInfoKind {
/// forward decls for types that could be
/// replaced with forward decls in the source
/// code. For dynamic C++ classes type info
-   /// is only emitted int the module that
+   /// is only emitted into the module that
/// contains the classe's vtable.
   FullDebugInfo/// Generate complete debug info.
 };


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