[PATCH] D49508: [Sema] Mark implicitly-inserted ICE's as being part of explicit cast (PR38166)

2018-07-21 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added inline comments.



Comment at: lib/Sema/SemaCast.cpp:94-101
+void updatePartOfExplicitCastFlags(CastExpr *CE) {
+  // Walk down from the CE to the OrigSrcExpr, and mark all immediate
+  // ImplicitCastExpr's as being part of ExplicitCastExpr. The original CE
+  // (which is a ExplicitCastExpr), and the OrigSrcExpr are not touched.
+  while (OrigSrcExpr.get() != CE->getSubExpr() &&
+ (CE = dyn_cast(CE->getSubExpr(
+CE->setIsPartOfExplicitCast(true);

rsmith wrote:
> You don't need to track the `OrigSrcExpr` here. You can just recurse down 
> through all the `ImplicitCastExpr`s (they're always all notionally part of 
> the explicit cast).
We do sometimes have `OrigSrcExpr` being `ImplicitCastExpr`.
https://godbolt.org/g/S5951G <- that `ImplicitCastExpr` would now get marked, 
even though it is `OrigSrcExpr`.
Is that expected?


Repository:
  rC Clang

https://reviews.llvm.org/D49508



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


[PATCH] D49508: [Sema] Mark implicitly-inserted ICE's as being part of explicit cast (PR38166)

2018-07-21 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added inline comments.



Comment at: include/clang/AST/Stmt.h:206
+bool PartOfExplicitCast : 1;
+unsigned BasePathSize : 32 - 6 - 1 - NumExprBits;
   };

rsmith wrote:
> lebedev.ri wrote:
> > rjmccall wrote:
> > > lebedev.ri wrote:
> > > > rjmccall wrote:
> > > > > This needs to be serialized.
> > > > Uhm, could you please explain what do you mean by 'serialized'?
> > > It needs to be preserved when writing an ICE into a PCH / module file.  
> > > See the ASTWriter / ASTReader.
> > Aha. I did add handling there but it raises questions:
> >   #  This will silently break with different AST serialization versions.
> >  I'm not sure how to handle it, since `VERSION_MINOR` isn't even read 
> > back.
> >   #  //Does// this need a test? How to write one?
> >  Like `./test/PCH/include-timestamp.cpp`, using `llvm-bcanalyzer`?
> Don't worry about breaking the serialization format. We do not maintain AST 
> file format compatibility in general (neither between major releases nor 
> between any two arbitrary SVN revisions). [We should probably maintain file 
> format compatibility between patch releases, but I don't think that works 
> right now because we check the full version number including the patch level 
> when reading a file.]
> 
> Please do add a test: what you need to do is create a PCH containing an 
> implicit cast expression and then import that AST file and do anything to 
> check that the value is preserved (such as inspecting the output of 
> `-ast-dump`). Maybe you could add this to the existing 
> `test/PCH/cxx_exprs.cpp` test, which already does most of what you want, but 
> doesn't have any `FileCheck` tests on the `-ast-dump` output yet.
Uhm, so i have tried to add a test.
With git master, the `-ast-dump` from the first runline of 
`test/PCH/cxx_exprs.cpp` contains:
```
|-TypedefDecl 0x55a348020b88  
col:44 referenced static_cast_result 'typeof (static_cast(0))':'void *'
| `-TypeOfExprType 0x55a348020b50 'typeof (static_cast(0))' sugar
|   |-ParenExpr 0x55a348020b28  'void *'
|   | `-CXXStaticCastExpr 0x55a348020af8  'void *' 
static_cast 
|   |   `-ImplicitCastExpr 0x55a348020ae0  'void *' 
|   | `-IntegerLiteral 0x55a348020aa8  'int' 0
|   `-PointerType 0x55a347fe6390 'void *'
| `-BuiltinType 0x55a347fe5b90 'void'
```
But the last runline (which uses PCH) does not have that.
Unfortunately i know next to nothing about PCH / AST serialization, so i'm not 
sure how to workaround that yet.
It does contain ``-`, so maybe i have to somehow 
force full deserialization?
{F6733062} {F6733063}


Repository:
  rC Clang

https://reviews.llvm.org/D49508



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


[PATCH] D49508: [Sema] Mark implicitly-inserted ICE's as being part of explicit cast (PR38166)

2018-07-21 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri updated this revision to Diff 156670.
lebedev.ri marked an inline comment as done.
lebedev.ri added a comment.

Partially address some of @rsmith's review notes, see reply notes for issues.


Repository:
  rC Clang

https://reviews.llvm.org/D49508

Files:
  include/clang/AST/Expr.h
  include/clang/AST/Stmt.h
  lib/AST/ASTDumper.cpp
  lib/Sema/SemaCast.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterDecl.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/PCH/cxx_exprs.cpp
  test/Sema/multistep-explicit-cast.c
  test/SemaCXX/multistep-explicit-cast.cpp
  test/SemaOpenCL/multistep-explicit-cast.cl

Index: test/SemaOpenCL/multistep-explicit-cast.cl
===
--- /dev/null
+++ test/SemaOpenCL/multistep-explicit-cast.cl
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -ast-dump %s | FileCheck %s
+// expected-no-diagnostics
+
+typedef __attribute__((ext_vector_type(2)))  char char2;
+
+void vectorIncrementDecrementOps() {
+  // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} vectorIncrementDecrementOps 'void (void)'{{$}}
+  // CHECK: CStyleCastExpr {{.*}}  'char2':'char __attribute__((ext_vector_type(2)))' {{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'char'  part_of_explicit_cast{{$}}
+  // CHECK-NEXT: IntegerLiteral {{.*}}  'int' 1{{$}}
+  char2 A = (char2)(1);
+  A++;
+}
Index: test/SemaCXX/multistep-explicit-cast.cpp
===
--- /dev/null
+++ test/SemaCXX/multistep-explicit-cast.cpp
@@ -0,0 +1,155 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsyntax-only -ast-dump %s | FileCheck %s
+
+// We are checking that implicit casts don't get marked with 'part_of_explicit_cast',
+// while in explicit casts, the implicitly-inserted implicit casts are marked with 'part_of_explicit_cast'
+
+unsigned char implicitcast_0(unsigned int x) {
+  // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_0 'unsigned char (unsigned int)'{{$}}
+  // CHECK: ImplicitCastExpr {{.*}}  'unsigned char' {{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'unsigned int' {{$}}
+  // CHECK-NEXT: DeclRefExpr {{.*}}  'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
+  return x;
+}
+
+signed char implicitcast_1(unsigned int x) {
+  // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_1 'signed char (unsigned int)'{{$}}
+  // CHECK: ImplicitCastExpr {{.*}}  'signed char' {{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'unsigned int' {{$}}
+  // CHECK-NEXT: DeclRefExpr {{.*}}  'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
+  return x;
+}
+
+unsigned char implicitcast_2(signed int x) {
+  // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_2 'unsigned char (int)'{{$}}
+  // CHECK: ImplicitCastExpr {{.*}}  'unsigned char' {{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'int' {{$}}
+  // CHECK-NEXT: DeclRefExpr {{.*}}  'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
+  return x;
+}
+
+signed char implicitcast_3(signed int x) {
+  // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} implicitcast_3 'signed char (int)'{{$}}
+  // CHECK: ImplicitCastExpr {{.*}}  'signed char' {{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'int' {{$}}
+  // CHECK-NEXT: DeclRefExpr {{.*}}  'int' lvalue ParmVar {{.*}} 'x' 'int'{{$}}
+  return x;
+}
+
+////
+
+unsigned char cstylecast_0(unsigned int x) {
+  // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_0 'unsigned char (unsigned int)'{{$}}
+  // CHECK: CStyleCastExpr {{.*}}  'unsigned char' {{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'unsigned char'  part_of_explicit_cast{{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'unsigned int'  part_of_explicit_cast{{$}}
+  // CHECK-NEXT: DeclRefExpr {{.*}}  'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
+  return (unsigned char)x;
+}
+
+signed char cstylecast_1(unsigned int x) {
+  // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_1 'signed char (unsigned int)'{{$}}
+  // CHECK: CStyleCastExpr {{.*}}  'signed char' {{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'signed char'  part_of_explicit_cast{{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'unsigned int'  part_of_explicit_cast{{$}}
+  // CHECK-NEXT: DeclRefExpr {{.*}}  'unsigned int' lvalue ParmVar {{.*}} 'x' 'unsigned int'{{$}}
+  return (signed char)x;
+}
+
+unsigned char cstylecast_2(signed int x) {
+  // CHECK: FunctionDecl {{.*}} <{{.*}}, line:{{.*}}> line:{{.*}} cstylecast_2 'unsigned char (int)'{{$}}
+  // CHECK: CStyleCastExpr {{.*}}  'unsigned char' {{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'unsigned char'  part_of_explicit_cast{{$}}
+  // CHECK-NEXT: ImplicitCastExpr {{.*}}  'int'  part_of_explicit_cast{{$}}
+  // CHECK-NEXT: DeclRefExpr {{.*}}  'int' lvalue ParmVar {{.

[PATCH] D49634: [libclang] Add support for getting property setter and getter names

2018-07-21 Thread Michael Wu via Phabricator via cfe-commits
michaelwu created this revision.

This allows libclang to access the actual names of property setters and getters 
without needing to go through the indexer API. Usually default names are used, 
but the property can specify a different name.


Repository:
  rC Clang

https://reviews.llvm.org/D49634

Files:
  include/clang-c/Index.h
  test/Index/property-getter-setter.m
  tools/c-index-test/c-index-test.c
  tools/libclang/CIndex.cpp
  tools/libclang/libclang.exports

Index: tools/libclang/libclang.exports
===
--- tools/libclang/libclang.exports
+++ tools/libclang/libclang.exports
@@ -31,6 +31,8 @@
 clang_Cursor_getNumArguments
 clang_Cursor_getObjCDeclQualifiers
 clang_Cursor_getObjCPropertyAttributes
+clang_Cursor_getObjCPropertyGetterName
+clang_Cursor_getObjCPropertySetterName
 clang_Cursor_getObjCSelectorIndex
 clang_Cursor_getOffsetOfField
 clang_Cursor_getSpellingNameRange
Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -7913,6 +7913,30 @@
   return Result;
 }
 
+CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
+  if (C.kind != CXCursor_ObjCPropertyDecl)
+return cxstring::createNull();
+
+  const ObjCPropertyDecl *PD = dyn_cast(getCursorDecl(C));
+  Selector sel = PD->getGetterName();
+  if (sel.isNull())
+return cxstring::createNull();
+
+  return cxstring::createDup(sel.getAsString());
+}
+
+CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
+  if (C.kind != CXCursor_ObjCPropertyDecl)
+return cxstring::createNull();
+
+  const ObjCPropertyDecl *PD = dyn_cast(getCursorDecl(C));
+  Selector sel = PD->getSetterName();
+  if (sel.isNull())
+return cxstring::createNull();
+
+  return cxstring::createDup(sel.getAsString());
+}
+
 unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
   if (!clang_isDeclaration(C.kind))
 return CXObjCDeclQualifier_None;
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -1103,6 +1103,34 @@
   }
 }
 
+if (Cursor.kind == CXCursor_ObjCPropertyDecl) {
+  CXString Name = clang_Cursor_getObjCPropertyGetterName(Cursor);
+  CXString Spelling = clang_getCursorSpelling(Cursor);
+  const char *CName = clang_getCString(Name);
+  const char *CSpelling = clang_getCString(Spelling);
+  if (CName && strcmp(CName, CSpelling)) {
+printf(" (getter=%s)", CName);
+  }
+  clang_disposeString(Spelling);
+  clang_disposeString(Name);
+}
+
+if (Cursor.kind == CXCursor_ObjCPropertyDecl) {
+  CXString Name = clang_Cursor_getObjCPropertySetterName(Cursor);
+  CXString Spelling = clang_getCursorSpelling(Cursor);
+  const char *CName = clang_getCString(Name);
+  const char *CSpelling = clang_getCString(Spelling);
+  char *DefaultSetter = malloc(strlen(CSpelling) + 5);
+  sprintf(DefaultSetter, "set%s:", CSpelling);
+  DefaultSetter[3] &= ~(1 << 5); // Make uppercase
+  if (CName && strcmp(CName, DefaultSetter)) {
+printf(" (setter=%s)", CName);
+  }
+  free(DefaultSetter);
+  clang_disposeString(Spelling);
+  clang_disposeString(Name);
+}
+
 {
   unsigned QT = clang_Cursor_getObjCDeclQualifiers(Cursor);
   if (QT != CXObjCDeclQualifier_None) {
Index: test/Index/property-getter-setter.m
===
--- /dev/null
+++ test/Index/property-getter-setter.m
@@ -0,0 +1,10 @@
+@interface Foo
+@property (assign,readwrite,getter=b,setter=c:) id a;
+@property (assign,readonly,getter=e) id d;
+@property (assign,readwrite) id f;
+@end
+
+// RUN: c-index-test -test-print-type-declaration
+// CHECK: ObjCPropertyDecl=a:2:52 [getter,assign,readwrite,setter,] (getter=b) (setter=c:) [typedeclaration=id] [typekind=ObjCId]
+// CHECK: ObjCPropertyDecl=d:3:41 [readonly,getter,assign,] (getter=e) [typedeclaration=id] [typekind=ObjCId]
+// CHECK: ObjCPropertyDecl=f:4:33 [assign,readwrite,] [typedeclaration=id] [typekind=ObjCId]
Index: include/clang-c/Index.h
===
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -4449,6 +4449,18 @@
 CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C,
  unsigned reserved);
 
+/**
+ * Given a cursor that represents a property declaration, return the
+ * name of the method that implements the getter.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C);
+
+/**
+ * Given a cursor that represents a property declaration, return the
+ * name of the method that implements the setter, if any.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertySetterName(CXCursor C);
+
 /**
 

[PATCH] D49635: [libclang 8/8] Add support for the flag_enum attribute

2018-07-21 Thread Michael Wu via Phabricator via cfe-commits
michaelwu created this revision.

This adds support to libclang for reading the flag_enum attribute.

This also bumps CINDEX_VERSION_MINOR for this patch series.


Repository:
  rC Clang

https://reviews.llvm.org/D49635

Files:
  include/clang-c/Index.h
  test/Index/attributes.c
  tools/libclang/CIndex.cpp
  tools/libclang/CXCursor.cpp


Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -78,6 +78,7 @@
 case attr::ObjCDesignatedInitializer: return 
CXCursor_ObjCDesignatedInitializer;
 case attr::ObjCRuntimeVisible: return CXCursor_ObjCRuntimeVisible;
 case attr::ObjCBoxable: return CXCursor_ObjCBoxable;
+case attr::FlagEnum: return CXCursor_FlagEnum;
   }
 
   return CXCursor_UnexposedAttr;
Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -5313,6 +5313,8 @@
 return cxstring::createRef("attribute(objc_runtime_visible)");
   case CXCursor_ObjCBoxable:
 return cxstring::createRef("attribute(objc_boxable)");
+  case CXCursor_FlagEnum:
+return cxstring::createRef("attribute(flag_enum)");
   case CXCursor_PreprocessingDirective:
 return cxstring::createRef("preprocessing directive");
   case CXCursor_MacroDefinition:
Index: test/Index/attributes.c
===
--- test/Index/attributes.c
+++ test/Index/attributes.c
@@ -8,6 +8,10 @@
 void const_fn() __attribute__((const));
 void noduplicate_fn() __attribute__((noduplicate));
 
+enum __attribute((flag_enum)) FlagEnum {
+  Foo
+};
+
 // CHECK: attributes.c:3:32: StructDecl=Test2:3:32 (Definition) Extent=[3:1 - 
5:2]
 // CHECK: attributes.c:3:23: attribute(packed)=packed Extent=[3:23 - 3:29]
 // CHECK: attributes.c:4:8: FieldDecl=a:4:8 (Definition) Extent=[4:3 - 4:9] 
[access=public]
@@ -18,3 +22,5 @@
 // CHECK: attributes.c:8:32: attribute(const)= Extent=[8:32 - 8:37]
 // CHECK: attributes.c:9:6: FunctionDecl=noduplicate_fn:9:6 Extent=[9:1 - 9:51]
 // CHECK: attributes.c:9:38: attribute(noduplicate)= Extent=[9:38 - 9:49]
+// CHECK: attributes.c:11:31: EnumDecl=FlagEnum:11:31 (Definition) 
Extent=[11:1 - 13:2]
+// CHECK: attributes.c:11:19: attribute(flag_enum)= Extent=[11:19 - 11:28]
Index: include/clang-c/Index.h
===
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -32,7 +32,7 @@
  * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
  */
 #define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 49
+#define CINDEX_VERSION_MINOR 50
 
 #define CINDEX_VERSION_ENCODE(major, minor) ( \
   ((major) * 1)   \
@@ -2586,7 +2586,8 @@
   CXCursor_ObjCDesignatedInitializer = 434,
   CXCursor_ObjCRuntimeVisible= 435,
   CXCursor_ObjCBoxable   = 436,
-  CXCursor_LastAttr  = CXCursor_ObjCBoxable,
+  CXCursor_FlagEnum  = 437,
+  CXCursor_LastAttr  = CXCursor_FlagEnum,
 
   /* Preprocessing */
   CXCursor_PreprocessingDirective= 500,


Index: tools/libclang/CXCursor.cpp
===
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -78,6 +78,7 @@
 case attr::ObjCDesignatedInitializer: return CXCursor_ObjCDesignatedInitializer;
 case attr::ObjCRuntimeVisible: return CXCursor_ObjCRuntimeVisible;
 case attr::ObjCBoxable: return CXCursor_ObjCBoxable;
+case attr::FlagEnum: return CXCursor_FlagEnum;
   }
 
   return CXCursor_UnexposedAttr;
Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -5313,6 +5313,8 @@
 return cxstring::createRef("attribute(objc_runtime_visible)");
   case CXCursor_ObjCBoxable:
 return cxstring::createRef("attribute(objc_boxable)");
+  case CXCursor_FlagEnum:
+return cxstring::createRef("attribute(flag_enum)");
   case CXCursor_PreprocessingDirective:
 return cxstring::createRef("preprocessing directive");
   case CXCursor_MacroDefinition:
Index: test/Index/attributes.c
===
--- test/Index/attributes.c
+++ test/Index/attributes.c
@@ -8,6 +8,10 @@
 void const_fn() __attribute__((const));
 void noduplicate_fn() __attribute__((noduplicate));
 
+enum __attribute((flag_enum)) FlagEnum {
+  Foo
+};
+
 // CHECK: attributes.c:3:32: StructDecl=Test2:3:32 (Definition) Extent=[3:1 - 5:2]
 // CHECK: attributes.c:3:23: attribute(packed)=packed Extent=[3:23 - 3:29]
 // CHECK: attributes.c:4:8: FieldDecl=a:4:8 (Definition) Extent=[4:3 - 4:9] [access=public]
@@ -18,3 +22,5 @@
 // CHECK: attributes.c:8:32: attribute(const)= Extent=[8:32 - 8:37]
 // CHECK: attributes.c:9:6: 

[PATCH] D41566: [Modules TS] Diagnose exported internal linkage declarations

2018-07-21 Thread Hamza Sood via Phabricator via cfe-commits
hamzasood updated this revision to Diff 156681.
hamzasood added a comment.

- Fixed the premature loop termination issue pointed out by @rsmith (and added 
a test case for it).
- Fixed a few small issues regarding diagnosing exported enum/struct/union 
declarations without a name (especially anonymous unions at namespace-scope).
- Factored out the loop body into a separate function to keep things tidy.


https://reviews.llvm.org/D41566

Files:
  include/clang/AST/DeclBase.h
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaDecl.cpp
  test/CXX/modules-ts/basic/basic.def.odr/p4/module.cpp
  test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
  test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
  test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p2.cpp
  test/SemaCXX/anonymous-union-export.cpp

Index: test/SemaCXX/anonymous-union-export.cpp
===
--- test/SemaCXX/anonymous-union-export.cpp
+++ test/SemaCXX/anonymous-union-export.cpp
@@ -1,6 +1,14 @@
 // RUN: %clang_cc1 -std=c++17 -fmodules-ts -emit-obj -verify -o %t.pcm %s
 
 export module M;
+
 export {
-union { bool a; }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}}
+union { bool a; }; // expected-error{{anonymous unions at namespace or global scope must be declared 'static'}} \
+   // expected-error{{anonymous unions at namespace or global scope cannot be exported}}
+
+static union { bool a; }; // expected-error{{anonymous unions at namespace or global scope cannot be exported}}
+}
+
+namespace {
+export union { bool a; }; // expected-error{{anonymous unions at namespace or global scope cannot be exported}}
 }
Index: test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p2.cpp
===
--- test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p2.cpp
+++ test/CXX/modules-ts/dcl.dcl/dcl.module/dcl.module.interface/p2.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fmodules-ts %s -emit-module-interface -verify -o /dev/null
+
+export module A;
+
+export namespace { } // expected-error {{unnamed namespace}}
+
+export static int n = 5; // expected-error {{internal linkage}}
+
+namespace { // expected-note 5 {{in this}}
+  export {
+int a = 1;// expected-error {{internal linkage}}
+void f() { }  // expected-error {{internal linkage}}
+class B { };  // expected-error {{internal linkage}}
+struct { } x; // expected-error {{internal linkage}}
+
+extern "C++" void g() { } // expected-error {{internal linkage}}
+  }
+}
+
+export namespace a {
+  namespace b {
+namespace c {
+  static int i = 3; // expected-error {{internal linkage}}
+}
+  }
+}
Index: test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
===
--- test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
+++ test/CXX/modules-ts/basic/basic.def.odr/p4/user.cpp
@@ -3,7 +3,6 @@
 
 // CHECK-DAG: @extern_var_exported = external {{(dso_local )?}}global
 // CHECK-DAG: @inline_var_exported = linkonce_odr {{(dso_local )?}}global
-// CHECK-DAG: @_ZW6ModuleE19static_var_exported = available_externally {{(dso_local )?}}global i32 0
 // CHECK-DAG: @const_var_exported = available_externally {{(dso_local )?}}constant i32 3
 
 import Module;
@@ -16,7 +15,6 @@
 
   (void)&extern_var_exported;
   (void)&inline_var_exported;
-  (void)&static_var_exported;
   (void)&const_var_exported;
 
   // Module-linkage declarations are not visible here.
Index: test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
===
--- test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
+++ test/CXX/modules-ts/basic/basic.def.odr/p4/module.cppm
@@ -11,7 +11,6 @@
 // can discard this global and its initializer (if any), and other TUs are not
 // permitted to run the initializer for this variable.
 // CHECK-DAG: @inline_var_exported = linkonce_odr {{(dso_local )?}}global
-// CHECK-DAG: @_ZW6ModuleE19static_var_exported = {{(dso_local )?}}global
 // CHECK-DAG: @const_var_exported = {{(dso_local )?}}constant
 //
 // CHECK-DAG: @_ZW6ModuleE25extern_var_module_linkage = external {{(dso_local )?}}global
@@ -58,32 +57,20 @@
 export module Module;
 
 export {
-  // FIXME: These should be ill-formed: you can't export an internal linkage
-  // symbol, per [dcl.module.interface]p2.
-  // CHECK: define {{(dso_local )?}}void {{.*}}@_ZW6ModuleE22unused_static_exportedv
-  static void unused_static_exported() {}
-  // CHECK: define {{(dso_local )?}}void {{.*}}@_ZW6ModuleE20used_static_exportedv
-  static void used_static_exported() {}
-
   inline void unused_inline_exported() {}
   inline void used_inline_exported() {}
 
   extern int extern_var_exported;
   inline int inline_var_exported;
-  // FIXME: This should be ill-formed: you can't export an internal linkage
-  // symbol

[PATCH] D47344: LWG 2843 "Unclear behavior of std::pmr::memory_resource::do_allocate()"

2018-07-21 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone updated this revision to Diff 156684.
Quuxplusone added a comment.

Fix the "zero-byte allocation might be misaligned" issue by just never trying 
to allocate zero bytes — try to allocate 1 byte instead.


Repository:
  rCXX libc++

https://reviews.llvm.org/D47344

Files:
  include/experimental/memory_resource
  src/experimental/memory_resource.cpp

Index: src/experimental/memory_resource.cpp
===
--- src/experimental/memory_resource.cpp
+++ src/experimental/memory_resource.cpp
@@ -8,6 +8,7 @@
 //===--===//
 
 #include "experimental/memory_resource"
+#include "memory"
 
 #ifndef _LIBCPP_HAS_NO_ATOMIC_HEADER
 #include "atomic"
@@ -23,38 +24,51 @@
 
 // new_delete_resource()
 
+#ifdef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+static bool is_aligned_to(void *ptr, size_t align)
+{
+void *p2 = ptr;
+size_t space = 1;
+void *result = _VSTD::align(align, 1, p2, space);
+return (result == ptr);
+}
+#endif
+
 class _LIBCPP_TYPE_VIS __new_delete_memory_resource_imp
 : public memory_resource
 {
-public:
-~__new_delete_memory_resource_imp() = default;
-
-protected:
-virtual void* do_allocate(size_t __size, size_t __align)
-{ return _VSTD::__libcpp_allocate(__size, __align); /* FIXME */}
+void *do_allocate(size_t bytes, size_t align) override
+{
+#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+return _VSTD::__libcpp_allocate(bytes, align);
+#else
+if (bytes == 0)
+bytes = 1;
+void *result = _VSTD::__libcpp_allocate(bytes, align);
+if (!is_aligned_to(result, align)) {
+_VSTD::__libcpp_deallocate(result, align);
+__throw_bad_alloc();
+}
+return result;
+#endif
+}
 
-virtual void do_deallocate(void * __p, size_t, size_t __align)
-{ _VSTD::__libcpp_deallocate(__p, __align); /* FIXME */ }
+void do_deallocate(void *p, size_t, size_t align) override
+{ _VSTD::__libcpp_deallocate(p, align); }
 
-virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
-{ return &__other == this; }
+bool do_is_equal(const memory_resource& other) const _NOEXCEPT override
+{ return &other == this; }
 };
 
 // null_memory_resource()
 
 class _LIBCPP_TYPE_VIS __null_memory_resource_imp
 : public memory_resource
 {
-public:
-~__null_memory_resource_imp() = default;
-
-protected:
-virtual void* do_allocate(size_t, size_t) {
-__throw_bad_alloc();
-}
-virtual void do_deallocate(void *, size_t, size_t) {}
-virtual bool do_is_equal(memory_resource const & __other) const _NOEXCEPT
-{ return &__other == this; }
+void *do_allocate(size_t, size_t) override { __throw_bad_alloc(); }
+void do_deallocate(void *, size_t, size_t) override {}
+bool do_is_equal(const memory_resource& other) const _NOEXCEPT override
+{ return &other == this; }
 };
 
 namespace {
Index: include/experimental/memory_resource
===
--- include/experimental/memory_resource
+++ include/experimental/memory_resource
@@ -195,7 +195,7 @@
 }
 
 _LIBCPP_INLINE_VISIBILITY
-void deallocate(_ValueType * __p, size_t __n) _NOEXCEPT {
+void deallocate(_ValueType * __p, size_t __n) {
 _LIBCPP_ASSERT(__n <= __max_size(),
"deallocate called for size which exceeds max_size()");
 __res_->deallocate(__p, __n * sizeof(_ValueType), alignof(_ValueType));
@@ -265,7 +265,7 @@
 
 template 
 _LIBCPP_INLINE_VISIBILITY
-void destroy(_Tp * __p) _NOEXCEPT
+void destroy(_Tp * __p)
 { __p->~_Tp(); }
 
 _LIBCPP_INLINE_VISIBILITY
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D47344: LWG 2843 "Unclear behavior of std::pmr::memory_resource::do_allocate()"

2018-07-21 Thread Arthur O'Dwyer via Phabricator via cfe-commits
Quuxplusone marked 5 inline comments as done.
Quuxplusone added inline comments.



Comment at: src/experimental/memory_resource.cpp:48
+#ifdef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
+if (__size != 0 && !is_aligned_to(result, __align)) {
+_VSTD::__libcpp_deallocate(result, __align);

Quuxplusone wrote:
> Quuxplusone wrote:
> > EricWF wrote:
> > > Also, I'm not sure about the `size != 0` check. The returned pointer may 
> > > be non-null and incorrectly aligned.
> > This was covered in my commit message/summary: "If n == 0, return an 
> > unspecified result."
> > However, I am chagrined to state that I have no idea where I got that idea! 
> > I can't find support for that anywhere in the current Standard (although 
> > I'm not sure if I missed it).
> > 
> > We must choose here between "allocating zero bytes sometimes returns an 
> > underaligned pointer" and "allocating zero bytes sometimes throws 
> > bad_alloc." Neither one seems like good QoI. But as I no longer see why I 
> > thought "underaligned pointer" was permitted, I will change it to 
> > "sometimes throws bad_alloc" and re-upload.
> Hm! This and your other comment play into each other unfortunately well. When 
> `size == 0`, the pointer we get back from `__libcpp_allocate` actually points 
> to zero bytes, which means that when I call `std::align` on it, I invoke 
> undefined behavior.
> 
> My new theory is "I don't care about that undefined behavior."  I'd still 
> rather take undefined-behavior-in-a-rare-case over 
> implementation-defined-behavior-in-all-cases, and I'm too lazy to implement 
> implementation-defined-behavior-only-in-a-rare-case unless you tell me to. :P
Now fixed. (The fix is always in the last place you look!)


Repository:
  rCXX libc++

https://reviews.llvm.org/D47344



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


[PATCH] D49589: [UBSan] Strengthen pointer checks in 'new' expressions

2018-07-21 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: lib/CodeGen/CodeGenFunction.h:380
+  /// True if sanitizer checks for current pointer value are generated.
+  bool PointerChecksAreEmitted = false;
+

I don't think this is a good way of doing this.  Using global state makes this 
unnecessarily difficult to reason about and can have unintended effects.  For 
example, you are unintentionally suppressing any checks that would be done as 
part of e.g. evaluating default arguments to the default constructor.

You should pass a parameter down that says whether checks are necessary.  You 
can also use that parameter to e.g. suppress checks when constructing local 
variables and temporaries, although you may already have an alternative 
mechanism for doing that.


Repository:
  rC Clang

https://reviews.llvm.org/D49589



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


[PATCH] D49638: [libcxxabi] Implement a GCC compatible SEH unwinding personality, __gxx_personality_seh0

2018-07-21 Thread Martin Storsjö via Phabricator via cfe-commits
mstorsjo created this revision.
mstorsjo added reviewers: compnerd, smeenai, rnk, zturner, majnemer, EricWF.
Herald added subscribers: ldionne, chrib.

This allows handling SEH based exceptions, with unwind functions provided by 
libgcc.


Repository:
  rCXXA libc++abi

https://reviews.llvm.org/D49638

Files:
  src/cxa_personality.cpp


Index: src/cxa_personality.cpp
===
--- src/cxa_personality.cpp
+++ src/cxa_personality.cpp
@@ -23,6 +23,16 @@
 #include "private_typeinfo.h"
 #include "unwind.h"
 
+#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+#include 
+#include 
+
+extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD,
+   void *, PCONTEXT,
+   PDISPATCHER_CONTEXT,
+   _Unwind_Personality_Fn);
+#endif
+
 /*
 Exception Header Layout:
 
@@ -934,12 +944,16 @@
 */
 
 #if !defined(_LIBCXXABI_ARM_EHABI)
+#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+static _Unwind_Reason_Code __gxx_personality_imp
+#else
 _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code
 #ifdef __USING_SJLJ_EXCEPTIONS__
 __gxx_personality_sj0
 #else
 __gxx_personality_v0
 #endif
+#endif
 (int version, _Unwind_Action actions, uint64_t 
exceptionClass,
  _Unwind_Exception* unwind_exception, _Unwind_Context* 
context)
 {
@@ -1022,6 +1036,17 @@
 // We were called improperly: neither a phase 1 or phase 2 search
 return _URC_FATAL_PHASE1_ERROR;
 }
+
+#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+extern "C" EXCEPTION_DISPOSITION
+__gxx_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame,
+   PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp)
+{
+  return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context, ms_disp,
+   __gxx_personality_imp);
+}
+#endif
+
 #else
 
 extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*,


Index: src/cxa_personality.cpp
===
--- src/cxa_personality.cpp
+++ src/cxa_personality.cpp
@@ -23,6 +23,16 @@
 #include "private_typeinfo.h"
 #include "unwind.h"
 
+#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+#include 
+#include 
+
+extern "C" EXCEPTION_DISPOSITION _GCC_specific_handler(PEXCEPTION_RECORD,
+   void *, PCONTEXT,
+   PDISPATCHER_CONTEXT,
+   _Unwind_Personality_Fn);
+#endif
+
 /*
 Exception Header Layout:
 
@@ -934,12 +944,16 @@
 */
 
 #if !defined(_LIBCXXABI_ARM_EHABI)
+#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+static _Unwind_Reason_Code __gxx_personality_imp
+#else
 _LIBCXXABI_FUNC_VIS _Unwind_Reason_Code
 #ifdef __USING_SJLJ_EXCEPTIONS__
 __gxx_personality_sj0
 #else
 __gxx_personality_v0
 #endif
+#endif
 (int version, _Unwind_Action actions, uint64_t exceptionClass,
  _Unwind_Exception* unwind_exception, _Unwind_Context* context)
 {
@@ -1022,6 +1036,17 @@
 // We were called improperly: neither a phase 1 or phase 2 search
 return _URC_FATAL_PHASE1_ERROR;
 }
+
+#if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__)
+extern "C" EXCEPTION_DISPOSITION
+__gxx_personality_seh0(PEXCEPTION_RECORD ms_exc, void *this_frame,
+   PCONTEXT ms_orig_context, PDISPATCHER_CONTEXT ms_disp)
+{
+  return _GCC_specific_handler(ms_exc, this_frame, ms_orig_context, ms_disp,
+   __gxx_personality_imp);
+}
+#endif
+
 #else
 
 extern "C" _Unwind_Reason_Code __gnu_unwind_frame(_Unwind_Exception*,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Clang-Tidy Problem when Exporting Fixes

2018-07-21 Thread Ahmad Nouralizadeh via cfe-commits
I ran clang-tidy in the root directory of the source code of an application
(MPlayer-1.3.0). Precisely, I use run-clang-tidy.py python script, as
follows:

run-clang-tidy.py -header-filter='.*'
-checks='-*,readability-braces-around-statements' -fix


I ran clang-tidy in the root directory of the source code of an application
(MPlayer-1.3.0). Precisely, I use run-clang-tidy.py python script, as
follows:

run-clang-tidy.py -header-filter='.*'
-checks='-*,readability-braces-around-statements' -fix

The commands database is also stored in the root directory in a file named
compile_commands.json. After gathering all fixes, it tries to apply them
but no fix is applied on any of the source files compiled from the
*inner* directories.
Here is the first part of the error report:

Applying fixes ...Described file './libavutil/internal.h' doesn't
exist. Ignoring...Described file './libavutil/x86/intmath.h' doesn't
exist. Ignoring...Described file 'libavformat/internal.h' doesn't
exist. Ignoring...Described file './libavcodec/bytestream.h' doesn't
exist. Ignoring...Described file './libavcodec/flac.h' doesn't exist.
Ignoring...Described file './libavcodec/get_bits.h' doesn't exist.
Ignoring...Described file './libavcodec/internal.h' doesn't exist.
Ignoring...Described file './libavcodec/mathops.h' doesn't exist.
Ignoring...Described file './libavcodec/put_bits.h' doesn't exist.
Ignoring...Described file 'libavformat/matroskaenc.c' doesn't exist.
Ignoring...Described file 'libavformat/subtitles.h' doesn't exist.
Ignoring...Described file 'libavformat/apngdec.c' doesn't exist.
Ignoring..

These files are compiled using the Makefile located in the folder ffmpeg.
For example, libavformat/apngdec.c is located at ./ffmpeg/libavformat/
apngdec.c where .is the root directory of MPlayer-1.3.0. How can I fix the
problem?
It seems that the fixes exported in yaml format stored relative paths.
This is because the compilation database generated using Bear is in
that format. The paths should become absolute before being exported to
yaml, similar to what is done at
"clang-tools-extra-6.0.0/clang-tidy/ClangTidy.cpp:Line131".
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r337470 - [Sema] Add a new warning, -Wmemset-transposed-args

2018-07-21 Thread Nico Weber via cfe-commits
This has a false positive on ffmpeg:

../../third_party/ffmpeg/libavcodec/options.c:273:64: error: 'size'
argument to memset is '0'; did you mean to transpose the last two
arguments? [-Werror,-Wmemset-transposed-args]
alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0);

With:

#define alloc_and_copy_or_fail(obj, size, pad) \
if (src->obj && size > 0) { \
dest->obj = av_malloc(size + pad); \
if (!dest->obj) \
goto fail; \
memcpy(dest->obj, src->obj, size); \
if (pad) \
memset(((uint8_t *) dest->obj) + size, 0, pad); \
}

(
https://cs.chromium.org/chromium/src/third_party/ffmpeg/libavcodec/options.c?q=alloc_and_copy_or_fail&sq=package:chromium&g=0&l=261
; https://bugs.chromium.org/p/chromium/issues/detail?id=866202)

Maybe the warning shouldn't fire if the memset is from a macro?

On Thu, Jul 19, 2018 at 12:51 PM Erik Pilkington via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Author: epilk
> Date: Thu Jul 19 09:46:15 2018
> New Revision: 337470
>
> URL: http://llvm.org/viewvc/llvm-project?rev=337470&view=rev
> Log:
> [Sema] Add a new warning, -Wmemset-transposed-args
>
> This diagnoses calls to memset that have the second and third arguments
> transposed, for example:
>
>   memset(buf, sizeof(buf), 0);
>
> This is done by checking if the third argument is a literal 0, or if the
> second
> is a sizeof expression (and the third isn't). The first check is also done
> for
> calls to bzero.
>
> Differential revision: https://reviews.llvm.org/D49112
>
> Added:
> cfe/trunk/test/Sema/transpose-memset.c
> Modified:
> cfe/trunk/include/clang/Basic/DiagnosticGroups.td
> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> cfe/trunk/lib/Sema/SemaChecking.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=337470&r1=337469&r2=337470&view=diff
>
> ==
> --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Thu Jul 19 09:46:15
> 2018
> @@ -443,6 +443,13 @@ def : DiagGroup<"synth">;
>  def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">;
>  def SizeofArrayDecay : DiagGroup<"sizeof-array-decay">;
>  def SizeofPointerMemaccess : DiagGroup<"sizeof-pointer-memaccess">;
> +def MemsetTransposedArgs : DiagGroup<"memset-transposed-args">;
> +def DynamicClassMemaccess : DiagGroup<"dynamic-class-memaccess">;
> +def NonTrivialMemaccess : DiagGroup<"nontrivial-memaccess">;
> +def SuspiciousBzero : DiagGroup<"suspicious-bzero">;
> +def SuspiciousMemaccess : DiagGroup<"suspicious-memaccess",
> +  [SizeofPointerMemaccess, DynamicClassMemaccess,
> +   NonTrivialMemaccess, MemsetTransposedArgs, SuspiciousBzero]>;
>  def StaticInInline : DiagGroup<"static-in-inline">;
>  def StaticLocalInInline : DiagGroup<"static-local-in-inline">;
>  def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">;
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=337470&r1=337469&r2=337470&view=diff
>
> ==
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jul 19
> 09:46:15 2018
> @@ -619,14 +619,14 @@ def warn_cstruct_memaccess : Warning<
>"%select{destination for|source of|first operand of|second operand of}0
> this "
>"%1 call is a pointer to record %2 that is not trivial to "
>"%select{primitive-default-initialize|primitive-copy}3">,
> -  InGroup>;
> +  InGroup;
>  def note_nontrivial_field : Note<
>"field is non-trivial to %select{copy|default-initialize}0">;
>  def warn_dyn_class_memaccess : Warning<
>"%select{destination for|source of|first operand of|second operand of}0
> this "
>"%1 call is a pointer to %select{|class containing a }2dynamic class
> %3; "
>"vtable pointer will be %select{overwritten|copied|moved|compared}4">,
> -  InGroup>;
> +  InGroup;
>  def note_bad_memaccess_silence : Note<
>"explicitly cast the pointer to silence this warning">;
>  def warn_sizeof_pointer_expr_memaccess : Warning<
> @@ -655,7 +655,19 @@ def note_memsize_comparison_paren : Note
>"did you mean to compare the result of %0 instead?">;
>  def note_memsize_comparison_cast_silence : Note<
>"explicitly cast the argument to size_t to silence this warning">;
> -
> +def warn_suspicious_sizeof_memset : Warning<
> +  "%select{'size' argument to memset is '0'|"
> +  "setting buffer to a 'sizeof' expression}0"
> +  "; did you mean to transpose the last two arguments?">,
> +  InGroup;
> +def note_suspicious_sizeof_memset_silence : Note<
> +  "%select{parenthesize the third argument|"
> +  "cast the second ar

Re: r337470 - [Sema] Add a new warning, -Wmemset-transposed-args

2018-07-21 Thread Arthur O'Dwyer via cfe-commits
In this case Clang is complaining about

memset(complicated-expr, 0, 0);

which means that transposing the last two arguments would not "fix"
anything. Clang ought to not complain in this case.
It doesn't have anything to do with coming from a macro; it's just that
*both* arguments are zero.
(I would also expect that `memset(complicated-expr, (unsigned char)fill,
(size_t)0)` shouldn't warn, either. But we had some disagreement that casts
to `(unsigned char)` resp. `(size_t)` should be the right way to shut up
the warning in the first place...)
Basically Clang should only be suggesting a swap (and thus complaining at
all) in the case that swapping the arguments would actually improve the
situation.

–Arthur

On Sat, Jul 21, 2018 at 1:33 PM, Nico Weber via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> This has a false positive on ffmpeg:
>
> ../../third_party/ffmpeg/libavcodec/options.c:273:64: error: 'size'
> argument to memset is '0'; did you mean to transpose the last two
> arguments? [-Werror,-Wmemset-transposed-args]
> alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0);
>
> With:
>
> #define alloc_and_copy_or_fail(obj, size, pad) \
> if (src->obj && size > 0) { \
> dest->obj = av_malloc(size + pad); \
> if (!dest->obj) \
> goto fail; \
> memcpy(dest->obj, src->obj, size); \
> if (pad) \
> memset(((uint8_t *) dest->obj) + size, 0, pad); \
> }
>
> (https://cs.chromium.org/chromium/src/third_party/
> ffmpeg/libavcodec/options.c?q=alloc_and_copy_or_fail&sq=
> package:chromium&g=0&l=261 ; https://bugs.chromium.org/p/
> chromium/issues/detail?id=866202)
>
> Maybe the warning shouldn't fire if the memset is from a macro?
>
> On Thu, Jul 19, 2018 at 12:51 PM Erik Pilkington via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> Author: epilk
>> Date: Thu Jul 19 09:46:15 2018
>> New Revision: 337470
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=337470&view=rev
>> Log:
>> [Sema] Add a new warning, -Wmemset-transposed-args
>>
>> This diagnoses calls to memset that have the second and third arguments
>> transposed, for example:
>>
>>   memset(buf, sizeof(buf), 0);
>>
>> This is done by checking if the third argument is a literal 0, or if the
>> second
>> is a sizeof expression (and the third isn't). The first check is also
>> done for
>> calls to bzero.
>>
>> Differential revision: https://reviews.llvm.org/D49112
>>
>> Added:
>> cfe/trunk/test/Sema/transpose-memset.c
>> Modified:
>> cfe/trunk/include/clang/Basic/DiagnosticGroups.td
>> cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> cfe/trunk/lib/Sema/SemaChecking.cpp
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
>> clang/Basic/DiagnosticGroups.td?rev=337470&r1=337469&r2=337470&view=diff
>> 
>> ==
>> --- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Thu Jul 19
>> 09:46:15 2018
>> @@ -443,6 +443,13 @@ def : DiagGroup<"synth">;
>>  def SizeofArrayArgument : DiagGroup<"sizeof-array-argument">;
>>  def SizeofArrayDecay : DiagGroup<"sizeof-array-decay">;
>>  def SizeofPointerMemaccess : DiagGroup<"sizeof-pointer-memaccess">;
>> +def MemsetTransposedArgs : DiagGroup<"memset-transposed-args">;
>> +def DynamicClassMemaccess : DiagGroup<"dynamic-class-memaccess">;
>> +def NonTrivialMemaccess : DiagGroup<"nontrivial-memaccess">;
>> +def SuspiciousBzero : DiagGroup<"suspicious-bzero">;
>> +def SuspiciousMemaccess : DiagGroup<"suspicious-memaccess",
>> +  [SizeofPointerMemaccess, DynamicClassMemaccess,
>> +   NonTrivialMemaccess, MemsetTransposedArgs, SuspiciousBzero]>;
>>  def StaticInInline : DiagGroup<"static-in-inline">;
>>  def StaticLocalInInline : DiagGroup<"static-local-in-inline">;
>>  def GNUStaticFloatInit : DiagGroup<"gnu-static-float-init">;
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/
>> DiagnosticSemaKinds.td?rev=337470&r1=337469&r2=337470&view=diff
>> 
>> ==
>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Jul 19
>> 09:46:15 2018
>> @@ -619,14 +619,14 @@ def warn_cstruct_memaccess : Warning<
>>"%select{destination for|source of|first operand of|second operand
>> of}0 this "
>>"%1 call is a pointer to record %2 that is not trivial to "
>>"%select{primitive-default-initialize|primitive-copy}3">,
>> -  InGroup>;
>> +  InGroup;
>>  def note_nontrivial_field : Note<
>>"field is non-trivial to %select{copy|default-initialize}0">;
>>  def warn_dyn_class_memaccess : Warning<
>>"%select{destination for|source of|first operand of|second operand
>> of}0 

[PATCH] D41627: [Modules TS] Fix namespace visibility

2018-07-21 Thread Hamza Sood via Phabricator via cfe-commits
hamzasood updated this revision to Diff 156689.
hamzasood added a comment.

- Don't assume that -fmodules-ts implies that we're in a TS module.
- Don't ignore private namespaces when calculating the ownership kind.


https://reviews.llvm.org/D41627

Files:
  include/clang/AST/DeclBase.h
  lib/AST/DeclBase.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/CXX/modules-ts/basic/basic.namespace/p1.cpp


Index: test/CXX/modules-ts/basic/basic.namespace/p1.cpp
===
--- test/CXX/modules-ts/basic/basic.namespace/p1.cpp
+++ test/CXX/modules-ts/basic/basic.namespace/p1.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fmodules-ts -DMODULE -emit-module-interface %s -o %t
+// RUN: %clang_cc1 -fmodules-ts -DUSER -fmodule-file=%t %s -verify
+// expected-no-diagnostics
+
+#ifdef MODULE
+export module A;
+namespace ns {
+  export class A { };
+}
+#endif
+
+#ifdef USER
+import A;
+ns::A a;
+#endif
Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -8866,6 +8866,21 @@
   // for the namespace has the declarations that showed up in that particular
   // namespace definition.
   PushDeclContext(NamespcScope, Namespc);
+
+  if (const Module *CurrentModule = getCurrentModule()) {
+// Under the Modules TS, a namespace with external linkage should always be
+// visible when imported, regardless of whether it's explicitly exported.
+const bool IsTSModule = CurrentModule->Kind == Module::ModuleInterfaceUnit 
||
+CurrentModule->Kind == 
Module::GlobalModuleFragment;
+if (IsTSModule &&
+!Namespc->isAnonymousNamespace() && 
!Namespc->isInAnonymousNamespace()) {
+  Namespc->setModuleOwnershipKind(
+CurrentModule->Kind == Module::ModuleKind::GlobalModuleFragment
+? Decl::ModuleOwnershipKind::Visible
+: Decl::ModuleOwnershipKind::VisibleWhenImported);
+}
+  }
+
   return Namespc;
 }
 
Index: lib/AST/DeclBase.cpp
===
--- lib/AST/DeclBase.cpp
+++ lib/AST/DeclBase.cpp
@@ -292,6 +292,23 @@
 // Out-of-line virtual method providing a home for Decl.
 Decl::~Decl() = default;
 
+Decl::ModuleOwnershipKind Decl::getModuleOwnershipKindForChildOf(DeclContext 
*DC) {
+  // Ignore public namespaces because they might be visible by default.
+  while (DC && DC->isNamespace() && !cast(DC)->isModulePrivate())
+DC = DC->getParent();
+
+  if (auto *D = cast_or_null(DC)) {
+auto MOK = D->getModuleOwnershipKind();
+if (MOK != ModuleOwnershipKind::Unowned &&
+(!D->isFromASTFile() || D->hasLocalOwningModuleStorage()))
+  return MOK;
+// If D is not local and we have no local module storage, then we don't
+// need to track module ownership at all.
+  }
+
+  return ModuleOwnershipKind::Unowned;
+}
+
 void Decl::setDeclContext(DeclContext *DC) {
   DeclCtx = DC;
 }
Index: include/clang/AST/DeclBase.h
===
--- include/clang/AST/DeclBase.h
+++ include/clang/AST/DeclBase.h
@@ -350,18 +350,7 @@
 
   /// Get the module ownership kind to use for a local lexical child of \p DC,
   /// which may be either a local or (rarely) an imported declaration.
-  static ModuleOwnershipKind getModuleOwnershipKindForChildOf(DeclContext *DC) 
{
-if (DC) {
-  auto *D = cast(DC);
-  auto MOK = D->getModuleOwnershipKind();
-  if (MOK != ModuleOwnershipKind::Unowned &&
-  (!D->isFromASTFile() || D->hasLocalOwningModuleStorage()))
-return MOK;
-  // If D is not local and we have no local module storage, then we don't
-  // need to track module ownership at all.
-}
-return ModuleOwnershipKind::Unowned;
-  }
+  static ModuleOwnershipKind getModuleOwnershipKindForChildOf(DeclContext *DC);
 
 protected:
   Decl(Kind DK, DeclContext *DC, SourceLocation L)


Index: test/CXX/modules-ts/basic/basic.namespace/p1.cpp
===
--- test/CXX/modules-ts/basic/basic.namespace/p1.cpp
+++ test/CXX/modules-ts/basic/basic.namespace/p1.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fmodules-ts -DMODULE -emit-module-interface %s -o %t
+// RUN: %clang_cc1 -fmodules-ts -DUSER -fmodule-file=%t %s -verify
+// expected-no-diagnostics
+
+#ifdef MODULE
+export module A;
+namespace ns {
+  export class A { };
+}
+#endif
+
+#ifdef USER
+import A;
+ns::A a;
+#endif
Index: lib/Sema/SemaDeclCXX.cpp
===
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -8866,6 +8866,21 @@
   // for the namespace has the declarations that showed up in that particular
   // namespace definition.
   PushDeclContext(NamespcScope, Namespc);
+
+  if (const Module *CurrentModule = getCurrentModule()) {
+// Under the Modules TS, a namespace with external linkage should always

[PATCH] D49634: [libclang 7/8] Add support for getting property setter and getter names

2018-07-21 Thread Michael Wu via Phabricator via cfe-commits
michaelwu updated this revision to Diff 156691.
michaelwu added a comment.

Fix test


https://reviews.llvm.org/D49634

Files:
  include/clang-c/Index.h
  test/Index/property-getter-setter.m
  tools/c-index-test/c-index-test.c
  tools/libclang/CIndex.cpp
  tools/libclang/libclang.exports

Index: tools/libclang/libclang.exports
===
--- tools/libclang/libclang.exports
+++ tools/libclang/libclang.exports
@@ -31,6 +31,8 @@
 clang_Cursor_getNumArguments
 clang_Cursor_getObjCDeclQualifiers
 clang_Cursor_getObjCPropertyAttributes
+clang_Cursor_getObjCPropertyGetterName
+clang_Cursor_getObjCPropertySetterName
 clang_Cursor_getObjCSelectorIndex
 clang_Cursor_getOffsetOfField
 clang_Cursor_getSpellingNameRange
Index: tools/libclang/CIndex.cpp
===
--- tools/libclang/CIndex.cpp
+++ tools/libclang/CIndex.cpp
@@ -7913,6 +7913,30 @@
   return Result;
 }
 
+CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
+  if (C.kind != CXCursor_ObjCPropertyDecl)
+return cxstring::createNull();
+
+  const ObjCPropertyDecl *PD = dyn_cast(getCursorDecl(C));
+  Selector sel = PD->getGetterName();
+  if (sel.isNull())
+return cxstring::createNull();
+
+  return cxstring::createDup(sel.getAsString());
+}
+
+CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
+  if (C.kind != CXCursor_ObjCPropertyDecl)
+return cxstring::createNull();
+
+  const ObjCPropertyDecl *PD = dyn_cast(getCursorDecl(C));
+  Selector sel = PD->getSetterName();
+  if (sel.isNull())
+return cxstring::createNull();
+
+  return cxstring::createDup(sel.getAsString());
+}
+
 unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
   if (!clang_isDeclaration(C.kind))
 return CXObjCDeclQualifier_None;
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -1103,6 +1103,34 @@
   }
 }
 
+if (Cursor.kind == CXCursor_ObjCPropertyDecl) {
+  CXString Name = clang_Cursor_getObjCPropertyGetterName(Cursor);
+  CXString Spelling = clang_getCursorSpelling(Cursor);
+  const char *CName = clang_getCString(Name);
+  const char *CSpelling = clang_getCString(Spelling);
+  if (CName && strcmp(CName, CSpelling)) {
+printf(" (getter=%s)", CName);
+  }
+  clang_disposeString(Spelling);
+  clang_disposeString(Name);
+}
+
+if (Cursor.kind == CXCursor_ObjCPropertyDecl) {
+  CXString Name = clang_Cursor_getObjCPropertySetterName(Cursor);
+  CXString Spelling = clang_getCursorSpelling(Cursor);
+  const char *CName = clang_getCString(Name);
+  const char *CSpelling = clang_getCString(Spelling);
+  char *DefaultSetter = malloc(strlen(CSpelling) + 5);
+  sprintf(DefaultSetter, "set%s:", CSpelling);
+  DefaultSetter[3] &= ~(1 << 5); // Make uppercase
+  if (CName && strcmp(CName, DefaultSetter)) {
+printf(" (setter=%s)", CName);
+  }
+  free(DefaultSetter);
+  clang_disposeString(Spelling);
+  clang_disposeString(Name);
+}
+
 {
   unsigned QT = clang_Cursor_getObjCDeclQualifiers(Cursor);
   if (QT != CXObjCDeclQualifier_None) {
Index: test/Index/property-getter-setter.m
===
--- /dev/null
+++ test/Index/property-getter-setter.m
@@ -0,0 +1,10 @@
+@interface Foo
+@property (assign,readwrite,getter=b,setter=c:) id a;
+@property (assign,readonly,getter=e) id d;
+@property (assign,readwrite) id f;
+@end
+
+// RUN: c-index-test -test-print-type-declaration %s | FileCheck %s
+// CHECK: ObjCPropertyDecl=a:2:52 [getter,assign,readwrite,setter,] (getter=b) (setter=c:) [typedeclaration=id] [typekind=ObjCId]
+// CHECK: ObjCPropertyDecl=d:3:41 [readonly,getter,assign,] (getter=e) [typedeclaration=id] [typekind=ObjCId]
+// CHECK: ObjCPropertyDecl=f:4:33 [assign,readwrite,] [typedeclaration=id] [typekind=ObjCId]
Index: include/clang-c/Index.h
===
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -4449,6 +4449,18 @@
 CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C,
  unsigned reserved);
 
+/**
+ * Given a cursor that represents a property declaration, return the
+ * name of the method that implements the getter.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C);
+
+/**
+ * Given a cursor that represents a property declaration, return the
+ * name of the method that implements the setter, if any.
+ */
+CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertySetterName(CXCursor C);
+
 /**
  * 'Qualifiers' written next to the return and parameter types in
  * Objective-C method declarations.
___
cfe-commits 

[PATCH] D36527: Implemented P0428R2 - Familiar template syntax for generic lambdas

2018-07-21 Thread Hamza Sood via Phabricator via cfe-commits
hamzasood updated this revision to Diff 156693.
hamzasood added a comment.

- Resolved merge conflicts


https://reviews.llvm.org/D36527

Files:
  include/clang/AST/DeclCXX.h
  include/clang/AST/DeclTemplate.h
  include/clang/AST/ExprCXX.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/Basic/DiagnosticParseKinds.td
  include/clang/Parse/Parser.h
  include/clang/Sema/ScopeInfo.h
  include/clang/Sema/Sema.h
  lib/AST/DeclCXX.cpp
  lib/AST/DeclPrinter.cpp
  lib/AST/ExprCXX.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/TypePrinter.cpp
  lib/Parse/ParseExprCXX.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaType.cpp
  test/CXX/temp/temp.decls/temp.variadic/p4.cpp
  test/CodeGenCXX/mangle-lambda-explicit-template-params.cpp
  test/Index/print-display-names.cpp
  test/PCH/cxx11-lambdas.mm
  test/PCH/cxx1y-lambdas.mm
  test/PCH/cxx2a-template-lambdas.cpp
  test/Parser/cxx2a-template-lambdas.cpp
  test/SemaCXX/cxx2a-template-lambdas.cpp
  unittests/AST/StmtPrinterTest.cpp
  unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
  unittests/Tooling/TestVisitor.h
  www/cxx_status.html

Index: www/cxx_status.html
===
--- www/cxx_status.html
+++ www/cxx_status.html
@@ -860,7 +860,7 @@
 
   template-parameter-list for generic lambdas
   http://wg21.link/p0428r2";>P0428R2
-  No
+  SVN
 
 
   Concepts
Index: unittests/Tooling/TestVisitor.h
===
--- unittests/Tooling/TestVisitor.h
+++ unittests/Tooling/TestVisitor.h
@@ -44,6 +44,8 @@
 Lang_CXX98,
 Lang_CXX11,
 Lang_CXX14,
+Lang_CXX17,
+Lang_CXX2a,
 Lang_OBJC,
 Lang_OBJCXX11,
 Lang_CXX = Lang_CXX98
@@ -60,6 +62,8 @@
   case Lang_CXX98: Args.push_back("-std=c++98"); break;
   case Lang_CXX11: Args.push_back("-std=c++11"); break;
   case Lang_CXX14: Args.push_back("-std=c++14"); break;
+  case Lang_CXX17: Args.push_back("-std=c++17"); break;
+  case Lang_CXX2a: Args.push_back("-std=c++2a"); break;
   case Lang_OBJC:
 Args.push_back("-ObjC");
 Args.push_back("-fobjc-runtime=macosx-10.12.0");
Index: unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
===
--- unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
+++ unittests/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp
@@ -0,0 +1,53 @@
+//===- unittest/Tooling/RecursiveASTVisitorTests/LambdaTemplateParams.cpp -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "TestVisitor.h"
+
+using namespace clang;
+
+namespace {
+
+// Matches (optional) explicit template parameters.
+class LambdaTemplateParametersVisitor
+  : public ExpectedLocationVisitor {
+public:
+  bool shouldVisitImplicitCode() const { return false; }
+
+  bool VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
+EXPECT_FALSE(D->isImplicit());
+Match(D->getName(), D->getLocStart());
+return true;
+  }
+
+  bool VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
+EXPECT_FALSE(D->isImplicit());
+Match(D->getName(), D->getLocStart());
+return true;
+  }
+
+  bool VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
+EXPECT_FALSE(D->isImplicit());
+Match(D->getName(), D->getLocStart());
+return true;
+  }
+};
+
+TEST(RecursiveASTVisitor, VisitsLambdaExplicitTemplateParameters) {
+  LambdaTemplateParametersVisitor Visitor;
+  Visitor.ExpectMatch("T",  2, 15);
+  Visitor.ExpectMatch("I",  2, 24);
+  Visitor.ExpectMatch("TT", 2, 31);
+  EXPECT_TRUE(Visitor.runOver(
+  "void f() { \n"
+  "  auto l = [] class TT>(auto p) { }; \n"
+  "}",
+  LambdaTemplateParametersVisitor::Lang_CXX2a));
+}
+
+} // end anonymous namespace
Index: unittests/AST/StmtPrinterTest.cpp
===
--- unittests/AST/StmtPrinterTest.cpp
+++ unittests/AST/StmtPrinterTest.cpp
@@ -106,78 +106,73 @@
   return ::testing::AssertionSuccess();
 }
 
-::testing::AssertionResult
-PrintedStmtCXX98Matches(StringRef Code, const StatementMatcher &NodeMatch,
-StringRef ExpectedPrinted) {
-  std::vector Args;
-  Args.push_back("-std=c++98");
-  Args.push_back("-Wno-unused-value");
-  return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted);
-}
-
-::testing::AssertionResult PrintedStmtCXX98Matches(
-  StringRef Code,
-  StringRef ContainingFunction,
-  StringRef ExpectedPrinted) {
-  std::vector Args;
-  Args.push

[PATCH] D49063: [libclang 1/8] Add support for ObjCObjectType

2018-07-21 Thread Michael Wu via Phabricator via cfe-commits
michaelwu updated this revision to Diff 156692.
michaelwu added a comment.

`clang_Type_getNumObjCTypeArgs` and `clang_Type_getNumObjCProtocolRefs` now 
return unsigned.

I've bumped `CINDEX_VERSION_MINOR` in https://reviews.llvm.org/D49635 , which 
is the last in this patch series.


https://reviews.llvm.org/D49063

Files:
  include/clang-c/Index.h
  test/Index/objc-typeargs-protocols.m
  test/Index/print-type.m
  tools/c-index-test/c-index-test.c
  tools/libclang/CXType.cpp
  tools/libclang/libclang.exports

Index: tools/libclang/libclang.exports
===
--- tools/libclang/libclang.exports
+++ tools/libclang/libclang.exports
@@ -98,6 +98,11 @@
 clang_Type_visitFields
 clang_Type_getNamedType
 clang_Type_isTransparentTagTypedef
+clang_Type_getObjCObjectBaseType
+clang_Type_getNumObjCProtocolRefs
+clang_Type_getObjCProtocolDecl
+clang_Type_getNumObjCTypeArgs
+clang_Type_getObjCTypeArg
 clang_VerbatimBlockLineComment_getText
 clang_VerbatimLineComment_getText
 clang_HTMLTagComment_getAsString
Index: tools/libclang/CXType.cpp
===
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -98,6 +98,7 @@
 TKCASE(Enum);
 TKCASE(Typedef);
 TKCASE(ObjCInterface);
+TKCASE(ObjCObject);
 TKCASE(ObjCObjectPointer);
 TKCASE(FunctionNoProto);
 TKCASE(FunctionProto);
@@ -575,6 +576,7 @@
 TKIND(Enum);
 TKIND(Typedef);
 TKIND(ObjCInterface);
+TKIND(ObjCObject);
 TKIND(ObjCObjectPointer);
 TKIND(FunctionNoProto);
 TKIND(FunctionProto);
@@ -1098,6 +1100,74 @@
   return MakeCXType(QT.getValueOr(QualType()), GetTU(CT));
 }
 
+CXType clang_Type_getObjCObjectBaseType(CXType CT) {
+  QualType T = GetQualType(CT);
+  if (T.isNull())
+return MakeCXType(QualType(), GetTU(CT));
+
+  const ObjCObjectType *OT = dyn_cast(T);
+  if (!OT)
+return MakeCXType(QualType(), GetTU(CT));
+
+  return MakeCXType(OT->getBaseType(), GetTU(CT));
+}
+
+unsigned clang_Type_getNumObjCProtocolRefs(CXType CT) {
+  QualType T = GetQualType(CT);
+  if (T.isNull())
+return 0;
+
+  const ObjCObjectType *OT = dyn_cast(T);
+  if (!OT)
+return 0;
+
+  return OT->getNumProtocols();
+}
+
+CXCursor clang_Type_getObjCProtocolDecl(CXType CT, unsigned i) {
+  QualType T = GetQualType(CT);
+  if (T.isNull())
+return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
+
+  const ObjCObjectType *OT = dyn_cast(T);
+  if (!OT)
+return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
+
+  const ObjCProtocolDecl *PD = OT->getProtocol(i);
+  if (!PD)
+return cxcursor::MakeCXCursorInvalid(CXCursor_NoDeclFound);
+
+  return cxcursor::MakeCXCursor(PD, GetTU(CT));
+}
+
+unsigned clang_Type_getNumObjCTypeArgs(CXType CT) {
+  QualType T = GetQualType(CT);
+  if (T.isNull())
+return 0;
+
+  const ObjCObjectType *OT = dyn_cast(T);
+  if (!OT)
+return 0;
+
+  return OT->getTypeArgs().size();
+}
+
+CXType clang_Type_getObjCTypeArg(CXType CT, unsigned i) {
+  QualType T = GetQualType(CT);
+  if (T.isNull())
+return MakeCXType(QualType(), GetTU(CT));
+
+  const ObjCObjectType *OT = dyn_cast(T);
+  if (!OT)
+return MakeCXType(QualType(), GetTU(CT));
+
+  const ArrayRef TA = OT->getTypeArgs();
+  if ((size_t)i >= TA.size())
+return MakeCXType(QualType(), GetTU(CT));
+
+  return MakeCXType(TA[i], GetTU(CT));
+}
+
 unsigned clang_Type_visitFields(CXType PT,
 CXFieldVisitor visitor,
 CXClientData client_data){
Index: tools/c-index-test/c-index-test.c
===
--- tools/c-index-test/c-index-test.c
+++ tools/c-index-test/c-index-test.c
@@ -1500,6 +1500,7 @@
  CXClientData d) {
   if (!clang_isInvalid(clang_getCursorKind(cursor))) {
 CXType T = clang_getCursorType(cursor);
+CXType PT = clang_getPointeeType(T);
 enum CXRefQualifierKind RQ = clang_Type_getCXXRefQualifier(T);
 PrintCursor(cursor, NULL);
 PrintTypeAndTypeKind(T, " [type=%s] [typekind=%s]");
@@ -1545,11 +1546,45 @@
 printf("]");
   }
 }
+/* Print ObjC base types, type arguments, and protocol list if available. */
+{
+  CXType BT = clang_Type_getObjCObjectBaseType(PT);
+  if (BT.kind != CXType_Invalid) {
+PrintTypeAndTypeKind(BT, " [basetype=%s] [basekind=%s]");
+  }
+}
+{
+  unsigned NumTypeArgs = clang_Type_getNumObjCTypeArgs(PT);
+  if (NumTypeArgs > 0) {
+unsigned i;
+printf(" [typeargs=");
+for (i = 0; i < NumTypeArgs; ++i) {
+  CXType TA = clang_Type_getObjCTypeArg(PT, i);
+  if (TA.kind != CXType_Invalid) {
+PrintTypeAndTypeKind(TA, " [%s] [%s]");
+  }
+}
+printf("]");
+  }
+}
+{
+  unsigned NumProtocols = clang_Type_getNumObjCProtocolRefs(PT);
+  if (NumProtoco

[PATCH] D49597: [ms] Fix mangling of vector types in QMM_Result contexts.

2018-07-21 Thread Nico Weber via Phabricator via cfe-commits
thakis added a comment.

rnk, since zturner is out until Thu, can you take a look?


https://reviews.llvm.org/D49597



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


[libcxx] r337649 - Implement a better copy_file.

2018-07-21 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Jul 21 19:00:53 2018
New Revision: 337649

URL: http://llvm.org/viewvc/llvm-project?rev=337649&view=rev
Log:
Implement a better copy_file.

This patch improves both the performance, and the safety of the
copy_file implementation.

The performance improvements are achieved by using sendfile on
Linux and copyfile on OS X when available.

The TOCTOU hardening is achieved by opening the source and
destination files and then using fstat to check their attributes to
see if we can copy them.

Unfortunately for the destination file, there is no way to open
it without accidentally creating it, so we first have to use
stat to determine if it exists, and if we should copy to it.
Then, once we're sure we should try to copy, we open the dest
file and ensure it names the same entity we previously stat'ed.

Added:

libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file_large.pass.cpp
Modified:
libcxx/trunk/include/fstream
libcxx/trunk/src/experimental/filesystem/operations.cpp

libcxx/trunk/test/std/experimental/filesystem/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp
libcxx/trunk/test/support/filesystem_test_helper.hpp
libcxx/trunk/test/support/rapid-cxx-test.hpp

Modified: libcxx/trunk/include/fstream
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/fstream?rev=337649&r1=337648&r2=337649&view=diff
==
--- libcxx/trunk/include/fstream (original)
+++ libcxx/trunk/include/fstream Sat Jul 21 19:00:53 2018
@@ -170,6 +170,7 @@ typedef basic_fstream wfstream;
 #include 
 #include <__locale>
 #include 
+#include 
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -217,10 +218,17 @@ public:
 #endif
 _LIBCPP_INLINE_VISIBILITY
 basic_filebuf* open(const string& __s, ios_base::openmode __mode);
+
+_LIBCPP_INLINE_VISIBILITY
+basic_filebuf* __open(int __fd, ios_base::openmode __mode);
 #endif
 basic_filebuf* close();
 
-protected:
+_LIBCPP_INLINE_VISIBILITY
+inline static const char*
+__make_mdstring(ios_base::openmode __mode) _NOEXCEPT;
+
+  protected:
 // 27.9.1.5 Overridden virtual functions:
 virtual int_type underflow();
 virtual int_type pbackfail(int_type __c = traits_type::eof());
@@ -234,25 +242,25 @@ protected:
 virtual void imbue(const locale& __loc);
 
 private:
-char*   __extbuf_;
-const char* __extbufnext_;
-const char* __extbufend_;
-char __extbuf_min_[8];
-size_t __ebs_;
-char_type* __intbuf_;
-size_t __ibs_;
-FILE* __file_;
-const codecvt* __cv_;
-state_type __st_;
-state_type __st_last_;
-ios_base::openmode __om_;
-ios_base::openmode __cm_;
-bool __owns_eb_;
-bool __owns_ib_;
-bool __always_noconv_;
+  char* __extbuf_;
+  const char* __extbufnext_;
+  const char* __extbufend_;
+  char __extbuf_min_[8];
+  size_t __ebs_;
+  char_type* __intbuf_;
+  size_t __ibs_;
+  FILE* __file_;
+  const codecvt* __cv_;
+  state_type __st_;
+  state_type __st_last_;
+  ios_base::openmode __om_;
+  ios_base::openmode __cm_;
+  bool __owns_eb_;
+  bool __owns_ib_;
+  bool __always_noconv_;
 
-bool __read_mode();
-void __write_mode();
+  bool __read_mode();
+  void __write_mode();
 };
 
 template 
@@ -473,6 +481,46 @@ basic_filebuf<_CharT, _Traits>::is_open(
 return __file_ != 0;
 }
 
+template 
+const char* basic_filebuf<_CharT, _Traits>::__make_mdstring(
+ios_base::openmode __mode) _NOEXCEPT {
+  switch (__mode & ~ios_base::ate) {
+  case ios_base::out:
+  case ios_base::out | ios_base::trunc:
+return "w";
+  case ios_base::out | ios_base::app:
+  case ios_base::app:
+return "a";
+  case ios_base::in:
+return "r";
+  case ios_base::in | ios_base::out:
+return "r+";
+  case ios_base::in | ios_base::out | ios_base::trunc:
+return "w+";
+  case ios_base::in | ios_base::out | ios_base::app:
+  case ios_base::in | ios_base::app:
+return "a+";
+  case ios_base::out | ios_base::binary:
+  case ios_base::out | ios_base::trunc | ios_base::binary:
+return "wb";
+  case ios_base::out | ios_base::app | ios_base::binary:
+  case ios_base::app | ios_base::binary:
+return "ab";
+  case ios_base::in | ios_base::binary:
+return "rb";
+  case ios_base::in | ios_base::out | ios_base::binary:
+return "r+b";
+  case ios_base::in | ios_base::out | ios_base::trunc | ios_base::binary:
+return "w+b";
+  case ios_base::in | ios_base::out | ios_base::app | ios_base::binary:
+  case ios_base::in | ios_base::app | ios_base::binary:
+return "a+b";
+  default:
+return nullptr;
+  }
+  _LIBCPP_UNREACHABLE();
+}
+
 #ifndef _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE
 template 
 basic_filebuf<_CharT, _Traits>*
@@ -481,79 +529,49 @@ basic_filebuf<_CharT, _Traits>::open(con
 basic_filebuf<_CharT, _Traits>* __rt = 0;
 if (__file_ == 0)
 {
+  if (const char* __mdstr = __make_md

Fwd: [llvm-dev] [LLVM.ORG] Scheduled Restart of llvm.org services Saturday 2018-07-21 @ 20:00PDT

2018-07-21 Thread Mike Edwards via cfe-commits
-- Forwarded message --
From: Mike Edwards 
Date: Sat, Jul 21, 2018 at 8:32 PM
Subject: Re: [llvm-dev] [LLVM.ORG] Scheduled Restart of llvm.org services
Saturday 2018-07-21 @ 20:00PDT
To: llvm-dev 


Hello,
The system update and restart of the llvm.org servers has been completed
successfully.  All systems appear to be back online and processing tasks
normally.  Thank for your patience and cooperation.  We hope you enjoy the
rest of your evening and weekend.

Respectfully,
Mike Edwards

On Thu, Jul 19, 2018 at 10:09 AM, Mike Edwards  wrote:

> Tl;dr: LLVM.org services will be restarted Saturday July 21, 2018 @
> 20:00PDT.
>
> Hi,
> We will be applying security updates to the llvm.org
>  servers on Saturday July 21st.  As a result we
> will need to restart the server at 20:00PDT.  The restart should only take
> a few minutes.  This server provides the following services to the
> community:
>
> * llvm.org website services
> * mailing list services
> * svn services
>
> We hope to have everything back up and running at or before 21:00PDT.  A
> follow up notification will be sent once the restart has been completed and
> the server is back online.  We understand this is a disruptive restart and
> we thank you for your patience and cooperation.
>
> Respectfully,
> Mike Edwards
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49643: [HIP] Add -target-cpu option for clang -cc1

2018-07-21 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl created this revision.
yaxunl added reviewers: rjmccall, tra, b-sumner, scchan.

https://reviews.llvm.org/D49643

Files:
  lib/Driver/ToolChains/HIP.cpp
  test/Driver/hip-toolchain.hip
  test/Driver/lit.local.cfg


Index: test/Driver/lit.local.cfg
===
--- test/Driver/lit.local.cfg
+++ test/Driver/lit.local.cfg
@@ -1,5 +1,5 @@
 config.suffixes = ['.c', '.cpp', '.h', '.m', '.mm', '.S', '.s', '.f90', '.f95',
-   '.cu', '.rs', '.cl']
+   '.cu', '.rs', '.cl', '.hip']
 config.substitutions = list(config.substitutions)
 config.substitutions.insert(0,
 ('%clang_cc1',
Index: test/Driver/hip-toolchain.hip
===
--- test/Driver/hip-toolchain.hip
+++ test/Driver/hip-toolchain.hip
@@ -14,14 +14,14 @@
 
 // CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa" 
 // CHECK-SAME: "-aux-triple" "x86_64--linux-gnu" "-emit-llvm-bc"
-// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-fcuda-is-device"
-// CHECK-SAME: {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip"
+// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx803"
+// CHECK-SAME: "-fcuda-is-device" {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip"
 // CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]]
 
 // CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
 // CHECK-SAME: "-aux-triple" "x86_64--linux-gnu" "-emit-llvm-bc"
-// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-fcuda-is-device"
-// CHECK-SAME: {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip"
+// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx803"
+// CHECK-SAME: "-fcuda-is-device" {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip"
 // CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]]
 
 // CHECK: [[LLVM_LINK:"*.llvm-link"]] [[A_BC]] [[B_BC]]
@@ -40,14 +40,14 @@
 
 // CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa" 
 // CHECK-SAME: "-aux-triple" "x86_64--linux-gnu" "-emit-llvm-bc"
-// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-fcuda-is-device"
-// CHECK-SAME: {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip"
+// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx900"
+// CHECK-SAME: "-fcuda-is-device" {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip"
 // CHECK-SAME: {{.*}} [[A_SRC]]
 
 // CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
 // CHECK-SAME: "-aux-triple" "x86_64--linux-gnu" "-emit-llvm-bc"
-// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-fcuda-is-device"
-// CHECK-SAME: {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip"
+// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx900"
+// CHECK-SAME: "-fcuda-is-device" {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip"
 // CHECK-SAME: {{.*}} [[B_SRC]]
 
 // CHECK: [[LLVM_LINK]] [[A_BC]] [[B_BC]]
Index: lib/Driver/ToolChains/HIP.cpp
===
--- lib/Driver/ToolChains/HIP.cpp
+++ lib/Driver/ToolChains/HIP.cpp
@@ -232,6 +232,8 @@
   assert(DeviceOffloadingKind == Action::OFK_HIP &&
  "Only HIP offloading kinds are supported for GPUs.");
 
+  CC1Args.push_back("-target-cpu");
+  CC1Args.push_back(DriverArgs.MakeArgStringRef(GpuArch));
   CC1Args.push_back("-fcuda-is-device");
 
   if (DriverArgs.hasFlag(options::OPT_fcuda_flush_denormals_to_zero,


Index: test/Driver/lit.local.cfg
===
--- test/Driver/lit.local.cfg
+++ test/Driver/lit.local.cfg
@@ -1,5 +1,5 @@
 config.suffixes = ['.c', '.cpp', '.h', '.m', '.mm', '.S', '.s', '.f90', '.f95',
-   '.cu', '.rs', '.cl']
+   '.cu', '.rs', '.cl', '.hip']
 config.substitutions = list(config.substitutions)
 config.substitutions.insert(0,
 ('%clang_cc1',
Index: test/Driver/hip-toolchain.hip
===
--- test/Driver/hip-toolchain.hip
+++ test/Driver/hip-toolchain.hip
@@ -14,14 +14,14 @@
 
 // CHECK: [[CLANG:".*clang.*"]] "-cc1" "-triple" "amdgcn-amd-amdhsa" 
 // CHECK-SAME: "-aux-triple" "x86_64--linux-gnu" "-emit-llvm-bc"
-// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-fcuda-is-device"
-// CHECK-SAME: {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip"
+// CHECK-SAME: {{.*}} "-main-file-name" "a.cu" {{.*}} "-target-cpu" "gfx803"
+// CHECK-SAME: "-fcuda-is-device" {{.*}} "-o" [[A_BC:".*bc"]] "-x" "hip"
 // CHECK-SAME: {{.*}} [[A_SRC:".*a.cu"]]
 
 // CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-amd-amdhsa"
 // CHECK-SAME: "-aux-triple" "x86_64--linux-gnu" "-emit-llvm-bc"
-// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-fcuda-is-device"
-// CHECK-SAME: {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip"
+// CHECK-SAME: {{.*}} "-main-file-name" "b.hip" {{.*}} "-target-cpu" "gfx803"
+// CHECK-SAME: "-fcuda-is-device" {{.*}} "-o" [[B_BC:".*bc"]] "-x" "hip"
 // CHECK-SAME: {{.*}} [[B_SRC:".*b.hip"]]
 
 // CHECK: [[LLVM_LINK:"*.llvm-link"]] [[A_BC]] [[B_BC]]
@@ -40,14 +40,14 @@
 
 // CHECK: [[CLANG]] "-cc1" "-triple" "amdgcn-am

r337653 - PR38257: don't perform ADL when instantiating a unary & operator that turns out

2018-07-21 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Sat Jul 21 22:21:47 2018
New Revision: 337653

URL: http://llvm.org/viewvc/llvm-project?rev=337653&view=rev
Log:
PR38257: don't perform ADL when instantiating a unary & operator that turns out
to be forming a pointer-to-member.

Added:
cfe/trunk/test/SemaTemplate/argument-dependent-lookup.cpp
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/TreeTransform.h

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=337653&r1=337652&r2=337653&view=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sat Jul 21 22:21:47 2018
@@ -4262,6 +4262,7 @@ public:
   ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc,
   tok::TokenKind Op, Expr *Input);
 
+  bool isQualifiedMemberAccess(Expr *E);
   QualType CheckAddressOfOperand(ExprResult &Operand, SourceLocation OpLoc);
 
   ExprResult CreateUnaryExprOrTypeTraitExpr(TypeSourceInfo *TInfo,

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=337653&r1=337652&r2=337653&view=diff
==
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sat Jul 21 22:21:47 2018
@@ -12809,7 +12809,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(So
 /// Determine whether the given expression is a qualified member
 /// access expression, of a form that could be turned into a pointer to member
 /// with the address-of operator.
-static bool isQualifiedMemberAccess(Expr *E) {
+bool Sema::isQualifiedMemberAccess(Expr *E) {
   if (DeclRefExpr *DRE = dyn_cast(E)) {
 if (!DRE->getQualifier())
   return false;

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=337653&r1=337652&r2=337653&view=diff
==
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Sat Jul 21 22:21:47 2018
@@ -12658,9 +12658,11 @@ TreeTransform::RebuildCXXOperat
 // -> is never a builtin operation.
 return SemaRef.BuildOverloadedArrowExpr(nullptr, First, OpLoc);
   } else if (Second == nullptr || isPostIncDec) {
-if (!First->getType()->isOverloadableType()) {
-  // The argument is not of overloadable type, so try to create a
-  // built-in unary operation.
+if (!First->getType()->isOverloadableType() ||
+(Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
+  // The argument is not of overloadable type, or this is an expression
+  // of the form &Class::member, so try to create a built-in unary
+  // operation.
   UnaryOperatorKind Opc
 = UnaryOperator::getOverloadedOpcode(Op, isPostIncDec);
 

Added: cfe/trunk/test/SemaTemplate/argument-dependent-lookup.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/argument-dependent-lookup.cpp?rev=337653&view=auto
==
--- cfe/trunk/test/SemaTemplate/argument-dependent-lookup.cpp (added)
+++ cfe/trunk/test/SemaTemplate/argument-dependent-lookup.cpp Sat Jul 21 
22:21:47 2018
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -verify %s
+// RUN: %clang_cc1 -verify %s -DHAVE_UNQUALIFIED_LOOKUP_RESULTS
+// expected-no-diagnostics
+
+namespace address_of {
+#ifdef HAVE_UNQUALIFIED_LOOKUP_RESULTS
+  struct Q {};
+  void operator&(Q);
+#endif
+
+  template struct A {
+static constexpr auto x = &T::value;
+  };
+
+  template struct B {
+constexpr int operator&() { return 123; }
+  };
+
+  template struct C {
+static_assert(sizeof(T) == 123, "");
+  };
+
+  struct X1 {
+static B value;
+  };
+  struct X2 : B {
+enum E { value };
+friend constexpr int operator&(E) { return 123; }
+  };
+
+  struct Y1 {
+C *value;
+  };
+  struct Y2 {
+C value();
+  };
+
+  // ok, uses ADL to find operator&:
+  static_assert(A::x == 123, "");
+  static_assert(A::x == 123, "");
+
+  // ok, does not use ADL so does not instantiate C:
+  static_assert(A::x == &Y1::value, "");
+  static_assert(A::x == &Y2::value, "");
+}


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