[PATCH] D31830: Emit invariant.group.barrier when using union field

2017-04-17 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: lib/CodeGen/CGExpr.cpp:3517
+CGM.getCodeGenOpts().StrictVTablePointers &&
+CGM.getCodeGenOpts().OptimizationLevel > 0)
+  addr = Address(Builder.CreateInvariantGroupBarrier(addr.getPointer()),

Prazek wrote:
> rjmccall wrote:
> > Prazek wrote:
> > > rjmccall wrote:
> > > > Checking for v-table pointers recursively isn't really that difficult, 
> > > > but if you really don't want to do that, please at least check for 
> > > > non-POD-ness or something so that this isn't kicking in for literally 
> > > > every struct type.
> > > ok, I am also planning to fix this in the later patch, because the same 
> > > problem arise when comparing 2 pointers to dynamic classe. 
> > > I would like to have a bit in CXXRecordDecl to remember if it has any 
> > > vptr inside that would calculate durring the construction. 
> > > My biggest fear is that if I won't cache it then it will be very slow.
> > We could repeat this work from scratch on every single union field access 
> > done by IRGen and it would still be way, way faster than doing anything 
> > extra on every record definition in the program.  The latter is done orders 
> > of magnitude more frequently than the former.
> This is a good point, and actually I don't need to check if class holds any 
> vptrs for the example I refered (comparing 2 pointers).
> Hovewer I still need to do it when someone casts pointer to class holding 
> vptrs to something that doesn't hold vptrs, and any pointer casts are much 
> more frequent than Record declarations.
What are you planning to do if someone casts to a pointer to incomplete type?

I am concerned that what these problems are really telling us is that this 
representation is not very good.


https://reviews.llvm.org/D31830



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


r300529 - Assert that a valid operator new/delete signature is always found by the coroutine body

2017-04-17 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Tue Apr 18 00:30:39 2017
New Revision: 300529

URL: http://llvm.org/viewvc/llvm-project?rev=300529=rev
Log:
Assert that a valid operator new/delete signature is always found by the 
coroutine body

Modified:
cfe/trunk/lib/Sema/SemaCoroutine.cpp

Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=300529=300528=300529=diff
==
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Tue Apr 18 00:30:39 2017
@@ -912,7 +912,9 @@ bool CoroutineStmtBuilder::makeNewAndDel
   OperatorNew, UnusedResult);
   }
 
-  if (OperatorNew && RequiresNoThrowAlloc) {
+  assert(OperatorNew && "expected definition of operator new to be found");
+
+  if (RequiresNoThrowAlloc) {
 const auto *FT = OperatorNew->getType()->getAs();
 if (!FT->isNothrow(S.Context, /*ResultIfDependent*/ false)) {
   S.Diag(OperatorNew->getLocation(),
@@ -924,9 +926,6 @@ bool CoroutineStmtBuilder::makeNewAndDel
 }
   }
 
-  // FIXME: Diagnose and handle the case where no matching operator new is 
found
-  //  (ie OperatorNew == nullptr)
-
   if ((OperatorDelete = findDeleteForPromise(S, Loc, PromiseType)) == nullptr)
 return false;
 


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


r300528 - Speculatively attempt to fix bot failures caused by recent coroutine changes.

2017-04-17 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Tue Apr 18 00:08:08 2017
New Revision: 300528

URL: http://llvm.org/viewvc/llvm-project?rev=300528=rev
Log:
Speculatively attempt to fix bot failures caused by recent coroutine changes.

Modified:
cfe/trunk/lib/Sema/SemaCoroutine.cpp

Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=300528=300527=300528=diff
==
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Tue Apr 18 00:08:08 2017
@@ -888,7 +888,7 @@ bool CoroutineStmtBuilder::makeNewAndDel
   FunctionDecl *OperatorDelete = nullptr;
   FunctionDecl *UnusedResult = nullptr;
   bool PassAlignment = false;
-  MultiExprArg PlacementArgs = None;
+  SmallVector PlacementArgs;
 
   S.FindAllocationFunctions(Loc, SourceRange(),
 /*UseGlobal*/ false, PromiseType,
@@ -904,7 +904,7 @@ bool CoroutineStmtBuilder::makeNewAndDel
 auto *StdNoThrow = buildStdNoThrowDeclRef(S, Loc);
 if (!StdNoThrow)
   return false;
-PlacementArgs = MultiExprArg(StdNoThrow);
+PlacementArgs = {StdNoThrow};
 OperatorNew = nullptr;
 S.FindAllocationFunctions(Loc, SourceRange(),
   /*UseGlobal*/ true, PromiseType,
@@ -924,6 +924,9 @@ bool CoroutineStmtBuilder::makeNewAndDel
 }
   }
 
+  // FIXME: Diagnose and handle the case where no matching operator new is 
found
+  //  (ie OperatorNew == nullptr)
+
   if ((OperatorDelete = findDeleteForPromise(S, Loc, PromiseType)) == nullptr)
 return false;
 
@@ -940,7 +943,7 @@ bool CoroutineStmtBuilder::makeNewAndDel
   if (NewRef.isInvalid())
 return false;
 
-  SmallVector NewArgs{FrameSize};
+  SmallVector NewArgs(1, FrameSize);
   for (auto Arg : PlacementArgs)
 NewArgs.push_back(Arg);
 


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


r300524 - [coroutines] Fix building of new/delete expressions when get_return_object_on_allocation_failure() is present.

2017-04-17 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Mon Apr 17 22:12:48 2017
New Revision: 300524

URL: http://llvm.org/viewvc/llvm-project?rev=300524=rev
Log:
[coroutines] Fix building of new/delete expressions when 
get_return_object_on_allocation_failure() is present.

Summary:
This patch implements [dcl.fct.def.coroutine]p8:
> The unqualified-id get_return_object_on_allocation_failure is looked up in 
> the scope of
> class P by class member access lookup (3.4.5). If a declaration is found, 
> ..., and if a 
> global allocation function is selected, the ::operator new(size_t, nothrow_t) 
> form shall be used.
> [...]
> The allocation function used in this case must have a non-throwing 
> noexcept-specification.

Reviewers: GorNishanov, rsmith, majnemer, aaron.ballman

Reviewed By: GorNishanov

Subscribers: cfe-commits

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

Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
cfe/trunk/test/SemaCXX/coroutines.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=300524=300523=300524=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Apr 17 22:12:48 
2017
@@ -8854,6 +8854,11 @@ def err_coroutine_invalid_func_context :
 def err_implied_coroutine_type_not_found : Error<
   "%0 type was not found; include  before defining "
   "a coroutine">;
+def err_implicit_coroutine_std_nothrow_type_not_found : Error<
+  "std::nothrow was not found; include  before defining a coroutine which 
"
+  "uses get_return_object_on_allocation_failure()">;
+def err_malformed_std_nothrow : Error<
+  "std::nothrow must be a valid variable declaration">;
 def err_malformed_std_coroutine_handle : Error<
   "std::experimental::coroutine_handle must be a class template">;
 def err_coroutine_handle_missing_member : Error<
@@ -8873,7 +8878,7 @@ def err_coroutine_promise_return_ill_for
   "%0 declares both 'return_value' and 'return_void'">;
 def note_coroutine_promise_implicit_await_transform_required_here : Note<
   "call to 'await_transform' implicitly required by 'co_await' here">;
-def note_coroutine_promise_call_implicitly_required : Note<
+def note_coroutine_promise_suspend_implicitly_required : Note<
   "call to '%select{initial_suspend|final_suspend}0' implicitly "
   "required by the %select{initial suspend point|final suspend point}0">;
 def err_coroutine_promise_unhandled_exception_required : Error<
@@ -8883,6 +,11 @@ def warn_coroutine_promise_unhandled_exc
   InGroup;
 def err_coroutine_promise_get_return_object_on_allocation_failure : Error<
   "%0: 'get_return_object_on_allocation_failure()' must be a static member 
function">;
+def err_coroutine_promise_new_requires_nothrow : Error<
+  "%0 is required to have a non-throwing noexcept specification when the 
promise "
+   "type declares 'get_return_object_on_allocation_failure()'">;
+def note_coroutine_promise_call_implicitly_required : Note<
+  "call to %0 implicitly required by coroutine function here">;
 }
 
 let CategoryName = "Documentation Issue" in {

Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=300524=300523=300524=diff
==
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Mon Apr 17 22:12:48 2017
@@ -454,7 +454,7 @@ static bool actOnCoroutineBodyStart(Sema
  /*IsImplicit*/ true);
 Suspend = S.ActOnFinishFullExpr(Suspend.get());
 if (Suspend.isInvalid()) {
-  S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
+  S.Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
   << ((Name == "initial_suspend") ? 0 : 1);
   S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
   return StmtError();
@@ -660,6 +660,39 @@ StmtResult Sema::BuildCoreturnStmt(Sourc
   return Res;
 }
 
+/// Look up the std::nothrow object.
+static Expr *buildStdNoThrowDeclRef(Sema , SourceLocation Loc) {
+  NamespaceDecl *Std = S.getStdNamespace();
+  assert(Std && "Should already be diagnosed");
+
+  LookupResult Result(S, ().get("nothrow"), Loc,
+  Sema::LookupOrdinaryName);
+  if (!S.LookupQualifiedName(Result, Std)) {
+// FIXME:  should have been included already.
+// If we require it to include  then this diagnostic is no longer
+// needed.
+S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
+return nullptr;
+  }
+
+  // FIXME: Mark the variable as ODR used. This currently does not work
+  // likely due to the scope at in 

[PATCH] D32147: [PR32479] Avoid newlib vasprintf, since it requires gnu extensions

2017-04-17 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF added a comment.

Why are GNU extensions not turned on? AFAIK Libc++ doesn't compile against any 
C library without GNU extensions enabled, including glibc and apple-libc.


https://reviews.llvm.org/D32147



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


r300523 - Debug Info: Remove special-casing of indirect function argument handling.

2017-04-17 Thread Adrian Prantl via cfe-commits
Author: adrian
Date: Mon Apr 17 20:22:01 2017
New Revision: 300523

URL: http://llvm.org/viewvc/llvm-project?rev=300523=rev
Log:
Debug Info: Remove special-casing of indirect function argument handling.

LLVM has changed the semantics of dbg.declare for describing function
arguments. After this patch a dbg.declare always takes the *address*
of a variable as the first argument, even if the argument is not an
alloca.

https://bugs.llvm.org/show_bug.cgi?id=32382
rdar://problem/31205000

Modified:
cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
cfe/trunk/test/CodeGen/debug-info-vla.c
cfe/trunk/test/CodeGenCXX/debug-info.cpp
cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl

Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=300523=300522=300523=diff
==
--- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon Apr 17 20:22:01 2017
@@ -3466,17 +3466,17 @@ void CGDebugInfo::EmitDeclare(const VarD
   // functions there won't be an implicit param at arg1 and
   // otherwise it is 'self' or 'this'.
   if (isa(VD) && ArgNo && *ArgNo == 1)
-Flags |= llvm::DINode::FlagObjectPointer;
-  if (auto *Arg = dyn_cast(Storage))
-if (Arg->getType()->isPointerTy() && !Arg->hasByValAttr() &&
-!VD->getType()->isPointerType())
-  Expr.push_back(llvm::dwarf::DW_OP_deref);
+  Flags |= llvm::DINode::FlagObjectPointer;
 
+  // Note: Older versions of clang used to emit byval references with an extra
+  // DW_OP_deref, because they referenced the IR arg directly instead of
+  // referencing an alloca. Newer versions of LLVM don't treat allocas
+  // differently from other function arguments when used in a dbg.declare.
   auto *Scope = cast(LexicalBlockStack.back());
-
   StringRef Name = VD->getName();
   if (!Name.empty()) {
 if (VD->hasAttr()) {
+  // Here, we need an offset *into* the alloca.
   CharUnits offset = CharUnits::fromQuantity(32);
   Expr.push_back(llvm::dwarf::DW_OP_plus);
   // offset of __forwarding field
@@ -3488,22 +3488,7 @@ void CGDebugInfo::EmitDeclare(const VarD
   // offset of x field
   offset = CGM.getContext().toCharUnitsFromBits(XOffset);
   Expr.push_back(offset.getQuantity());
-
-  // Create the descriptor for the variable.
-  auto *D = ArgNo
-? DBuilder.createParameterVariable(Scope, VD->getName(),
-   *ArgNo, Unit, Line, Ty)
-: DBuilder.createAutoVariable(Scope, VD->getName(), Unit,
-  Line, Ty, Align);
-
-  // Insert an llvm.dbg.declare into the current block.
-  DBuilder.insertDeclare(
-  Storage, D, DBuilder.createExpression(Expr),
-  llvm::DebugLoc::get(Line, Column, Scope, CurInlinedAt),
-  Builder.GetInsertBlock());
-  return;
-} else if (isa(VD->getType()))
-  Expr.push_back(llvm::dwarf::DW_OP_deref);
+}
   } else if (const auto *RT = dyn_cast(VD->getType())) {
 // If VD is an anonymous union then Storage represents value for
 // all union fields.
@@ -3606,8 +3591,7 @@ void CGDebugInfo::EmitDeclareOfBlockDecl
   ->getElementOffset(blockInfo.getCapture(VD).getIndex()));
 
   SmallVector addr;
-  if (isa(Storage))
-addr.push_back(llvm::dwarf::DW_OP_deref);
+  addr.push_back(llvm::dwarf::DW_OP_deref);
   addr.push_back(llvm::dwarf::DW_OP_plus);
   addr.push_back(offset.getQuantity());
   if (isByRef) {
@@ -3633,12 +3617,11 @@ void CGDebugInfo::EmitDeclareOfBlockDecl
   // Insert an llvm.dbg.declare into the current block.
   auto DL =
   llvm::DebugLoc::get(Line, Column, LexicalBlockStack.back(), 
CurInlinedAt);
+  auto *Expr = DBuilder.createExpression(addr);
   if (InsertPoint)
-DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(addr), DL,
-   InsertPoint);
+DBuilder.insertDeclare(Storage, D, Expr, DL, InsertPoint);
   else
-DBuilder.insertDeclare(Storage, D, DBuilder.createExpression(addr), DL,
-   Builder.GetInsertBlock());
+DBuilder.insertDeclare(Storage, D, Expr, DL, Builder.GetInsertBlock());
 }
 
 void CGDebugInfo::EmitDeclareOfArgVariable(const VarDecl *VD, llvm::Value *AI,

Modified: cfe/trunk/test/CodeGen/debug-info-vla.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/debug-info-vla.c?rev=300523=300522=300523=diff
==
--- cfe/trunk/test/CodeGen/debug-info-vla.c (original)
+++ cfe/trunk/test/CodeGen/debug-info-vla.c Mon Apr 17 20:22:01 2017
@@ -4,8 +4,8 @@ void testVLAwithSize(int s)
 {
 // CHECK: dbg.declare
 // CHECK: dbg.declare({{.*}}, metadata ![[VAR:.*]], metadata ![[EXPR:.*]])
-// CHECK: ![[VAR]] = !DILocalVariable(name: 

[PATCH] D32147: [PR32479] Avoid newlib vasprintf, since it requires gnu extensions

2017-04-17 Thread Ben Craig via Phabricator via cfe-commits
bcraig updated this revision to Diff 95520.
bcraig added reviewers: jyknight, mclow.lists, EricWF.
bcraig added a subscriber: cfe-commits.

https://reviews.llvm.org/D32147

Files:
  include/__bsd_locale_fallbacks.h
  include/__config


Index: include/__config
===
--- include/__config
+++ include/__config
@@ -871,6 +871,10 @@
 #endif
 #endif
 
+#if defined(_NEWLIB_VERSION)
+#define _LIBCPP_HAS_NO_ASPRINTF 1
+#endif
+
 #ifdef __FreeBSD__
 #define _DECLARE_C99_LDBL_MATH 1
 #endif
Index: include/__bsd_locale_fallbacks.h
===
--- include/__bsd_locale_fallbacks.h
+++ include/__bsd_locale_fallbacks.h
@@ -118,7 +118,26 @@
 va_list __va;
 va_start(__va, __format);
 __locale_raii __current( uselocale(__l), uselocale );
+#if _LIBCPP_HAS_NO_ASPRINTF
+va_list __va2;
+va_copy(__va2, __va);
+int __res = vsnprintf(0, 0, __format, __va2);
+va_end(__va2);
+if(__res < 0)
+{
+va_end(__va);
+return __res;
+}
+*__s = (char *)malloc(__res+1);
+if(*__s == 0)
+{
+va_end(__va);
+return -1;
+}
+vsnprintf(*__s, __res+1, __format, __va);
+#else
 int __res = vasprintf(__s, __format, __va);
+#endif
 va_end(__va);
 return __res;
 }


Index: include/__config
===
--- include/__config
+++ include/__config
@@ -871,6 +871,10 @@
 #endif
 #endif
 
+#if defined(_NEWLIB_VERSION)
+#define _LIBCPP_HAS_NO_ASPRINTF 1
+#endif
+
 #ifdef __FreeBSD__
 #define _DECLARE_C99_LDBL_MATH 1
 #endif
Index: include/__bsd_locale_fallbacks.h
===
--- include/__bsd_locale_fallbacks.h
+++ include/__bsd_locale_fallbacks.h
@@ -118,7 +118,26 @@
 va_list __va;
 va_start(__va, __format);
 __locale_raii __current( uselocale(__l), uselocale );
+#if _LIBCPP_HAS_NO_ASPRINTF
+va_list __va2;
+va_copy(__va2, __va);
+int __res = vsnprintf(0, 0, __format, __va2);
+va_end(__va2);
+if(__res < 0)
+{
+va_end(__va);
+return __res;
+}
+*__s = (char *)malloc(__res+1);
+if(*__s == 0)
+{
+va_end(__va);
+return -1;
+}
+vsnprintf(*__s, __res+1, __format, __va);
+#else
 int __res = vasprintf(__s, __format, __va);
+#endif
 va_end(__va);
 return __res;
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32146: PR32476: __nop_locale_mgmt.h not needed with newlib 2.5+

2017-04-17 Thread Ben Craig via Phabricator via cfe-commits
bcraig created this revision.

newlib 2.5 added the locale management functions, and so our stub 
__nop_locale_mgmt.h shouldn't be included, as it conflicts with newlibs 
definitions.  newlib 2.4 and earlier still need the header though.

Patch by Martin J. O'Riordan


https://reviews.llvm.org/D32146

Files:
  include/support/newlib/xlocale.h


Index: include/support/newlib/xlocale.h
===
--- include/support/newlib/xlocale.h
+++ include/support/newlib/xlocale.h
@@ -16,7 +16,11 @@
 #include 
 #include 
 #include 
+#if defined(__NEWLIB__) && (__NEWLIB__ == 2) \
+&& defined(__NEWLIB_MINOR__) && (__NEWLIB_MINOR__ >= 5) \
+&& (!defined(__POSIX_VISIBLE) || (__POSIX_VISIBLE < 200809))
 #include 
+#endif
 #include 
 #include 
 


Index: include/support/newlib/xlocale.h
===
--- include/support/newlib/xlocale.h
+++ include/support/newlib/xlocale.h
@@ -16,7 +16,11 @@
 #include 
 #include 
 #include 
+#if defined(__NEWLIB__) && (__NEWLIB__ == 2) \
+&& defined(__NEWLIB_MINOR__) && (__NEWLIB_MINOR__ >= 5) \
+&& (!defined(__POSIX_VISIBLE) || (__POSIX_VISIBLE < 200809))
 #include 
+#endif
 #include 
 #include 
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[libcxx] r300516 - Allow a standard library to implement conditional noexcept for optional and unique_ptr hash functions.

2017-04-17 Thread Billy Robert O'Neal III via cfe-commits
Author: bion
Date: Mon Apr 17 19:19:50 2017
New Revision: 300516

URL: http://llvm.org/viewvc/llvm-project?rev=300516=rev
Log:
Allow a standard library to implement conditional noexcept for optional and 
unique_ptr hash functions.

These tests were unconditionally asserting that optional and unique_ptr declare 
throwing hashes, but MSVC++ implements conditional noexcept forwarding that of 
the underlying hash function. As a result we were failing these tests but 
there's nothing forbidding strengthening noexcept in that way.

Changed the ASSERT_NOT_NOEXCEPT asserts to use types which themselves have 
non-noexcept hash functions.

Modified:

libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp
libcxx/trunk/test/std/utilities/optional/optional.hash/hash.pass.cpp

Modified: 
libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp?rev=300516=300515=300516=diff
==
--- 
libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/utilities/memory/util.smartptr/util.smartptr.hash/hash_unique_ptr.pass.cpp
 Mon Apr 17 19:19:50 2017
@@ -50,7 +50,7 @@ namespace std {
 
 template 
 struct hash<::min_pointer>> {
-  size_t operator()(::min_pointer> p) 
const noexcept(false) {
+  size_t operator()(::min_pointer> p) 
const TEST_NOEXCEPT_FALSE {
 if (!p) return 0;
 return std::hash{}(std::addressof(*p));
   }
@@ -67,12 +67,16 @@ int main()
 int* ptr = new int;
 std::unique_ptr p(ptr);
 std::hash f;
-ASSERT_NOT_NOEXCEPT(f(p));
 std::size_t h = f(p);
 assert(h == std::hash()(ptr));
   }
 #if TEST_STD_VER >= 11
   {
+std::unique_ptr> pThrowingHash;
+std::hash>> fThrowingHash;
+ASSERT_NOT_NOEXCEPT(fThrowingHash(pThrowingHash));
+  }
+  {
 test_enabled_with_deleter();
 test_enabled_with_deleter>();
 test_enabled_with_deleter();

Modified: libcxx/trunk/test/std/utilities/optional/optional.hash/hash.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/optional/optional.hash/hash.pass.cpp?rev=300516=300515=300516=diff
==
--- libcxx/trunk/test/std/utilities/optional/optional.hash/hash.pass.cpp 
(original)
+++ libcxx/trunk/test/std/utilities/optional/optional.hash/hash.pass.cpp Mon 
Apr 17 19:19:50 2017
@@ -26,7 +26,7 @@ namespace std {
 
 template <>
 struct hash {
-  size_t operator()(B const&) noexcept(false) { return 0; }
+  size_t operator()(B const&) TEST_NOEXCEPT_FALSE { return 0; }
 };
 
 }
@@ -37,10 +37,16 @@ int main()
 const std::size_t nullopt_hash =
 std::hash{}(optional{});
 
+
+{
+optional opt;
+ASSERT_NOT_NOEXCEPT(std::hash()(opt));
+ASSERT_NOT_NOEXCEPT(std::hash()(opt));
+}
+
 {
 typedef int T;
 optional opt;
-ASSERT_NOT_NOEXCEPT(std::hash()(opt));
 assert(std::hash{}(opt) == nullopt_hash);
 opt = 2;
 assert(std::hash{}(opt) == std::hash{}(*opt));
@@ -48,7 +54,6 @@ int main()
 {
 typedef std::string T;
 optional opt;
-ASSERT_NOT_NOEXCEPT(std::hash()(opt));
 assert(std::hash{}(opt) == nullopt_hash);
 opt = std::string("123");
 assert(std::hash{}(opt) == std::hash{}(*opt));
@@ -56,7 +61,6 @@ int main()
 {
 typedef std::unique_ptr T;
 optional opt;
-ASSERT_NOT_NOEXCEPT(std::hash()(opt));
 assert(std::hash{}(opt) == nullopt_hash);
 opt = std::unique_ptr(new int(3));
 assert(std::hash{}(opt) == std::hash{}(*opt));


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


[PATCH] D32144: [Coverage] Don't emit mappings for functions in dependent contexts (fixes PR32679)

2017-04-17 Thread Vedant Kumar via Phabricator via cfe-commits
vsk created this revision.

The coverage implementation marks functions which won't be emitted as
'deferred', so that it can emit empty coverage regions for them later
(once their linkages are known).

Functions in dependent contexts are an exception: if there isn't a full
instantiation of a function, it shouldn't be marked 'deferred'. We've
been breaking that rule without much consequence because we just ended
up with useless, extra, empty coverage mappings. With PR32679, this
behavior finally caused a crash, because clang marked a partial template
specialization as 'deferred', causing the MS mangler to choke in its
delayed-template-parsing mode:

  error: cannot mangle this template type parameter type yet
  (http://bugs.llvm.org/show_bug.cgi?id=32679)

Fix this by checking if a decl's context is a dependent context before
marking it 'deferred'.

Based on a patch by Adam Folwarczny!


https://reviews.llvm.org/D32144

Files:
  lib/CodeGen/ModuleBuilder.cpp
  test/CoverageMapping/pr32679.cpp


Index: test/CoverageMapping/pr32679.cpp
===
--- /dev/null
+++ test/CoverageMapping/pr32679.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -cc1 -triple i686-pc-windows-msvc19.0.0 -emit-obj 
-fprofile-instrument=clang -std=c++14 -fdelayed-template-parsing 
-fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name 
pr32679.cpp -o - %s | FileCheck %s -check-prefix=MSABI -implicit-check-not=f2
+// RUN: %clang_cc1 -cc1 -triple %itanium_abi_triple -emit-obj 
-fprofile-instrument=clang -std=c++14 -fcoverage-mapping -dump-coverage-mapping 
-emit-llvm-only -main-file-name pr32679.cpp -o - %s | FileCheck %s 
-check-prefix=ITANIUM -implicit-check-not=f2
+
+template 
+struct CreateSpecialization;
+
+template 
+struct CreateSpecialization {
+  static constexpr T f1() { return 0; }
+  static constexpr T f2() { return 0; }
+};
+
+int main() {
+  CreateSpecialization::f1();
+
+  // Don't emit coverage mapping info for functions in dependent contexts.
+  //
+  // E.g we never fully instantiate CreateSpecialization::f2(), so there
+  // should be no mapping for it.
+
+  return 0;
+}
+
+// MSABI: main:
+// MSABI-NEXT:   File 0, [[@LINE-12]]:12 -> [[@LINE-3]]:2 = #0
+// MSABI-NEXT: ?f1@?$CreateSpecialization@H$0A@@@SAHXZ:
+// MSABI-NEXT:   File 0, [[@LINE-18]]:27 -> [[@LINE-18]]:40 = #0
+
+// ITANIUM: main:
+// ITANIUM-NEXT:   File 0, [[@LINE-17]]:12 -> [[@LINE-8]]:2 = #0
+// ITANIUM-NEXT: _ZN20CreateSpecializationIiLi0EE2f1Ev:
+// ITANIUM-NEXT:   File 0, [[@LINE-23]]:27 -> [[@LINE-23]]:40 = #0
Index: lib/CodeGen/ModuleBuilder.cpp
===
--- lib/CodeGen/ModuleBuilder.cpp
+++ lib/CodeGen/ModuleBuilder.cpp
@@ -197,7 +197,8 @@
   // Provide some coverage mapping even for methods that aren't emitted.
   // Don't do this for templated classes though, as they may not be
   // instantiable.
-  if (!MD->getParent()->getDescribedClassTemplate())
+  if (!MD->getParent()->isDependentContext() &&
+  !MD->getParent()->getDescribedClassTemplate())
 Builder->AddDeferredUnusedCoverageMapping(MD);
 }
 


Index: test/CoverageMapping/pr32679.cpp
===
--- /dev/null
+++ test/CoverageMapping/pr32679.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -cc1 -triple i686-pc-windows-msvc19.0.0 -emit-obj -fprofile-instrument=clang -std=c++14 -fdelayed-template-parsing -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name pr32679.cpp -o - %s | FileCheck %s -check-prefix=MSABI -implicit-check-not=f2
+// RUN: %clang_cc1 -cc1 -triple %itanium_abi_triple -emit-obj -fprofile-instrument=clang -std=c++14 -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name pr32679.cpp -o - %s | FileCheck %s -check-prefix=ITANIUM -implicit-check-not=f2
+
+template 
+struct CreateSpecialization;
+
+template 
+struct CreateSpecialization {
+  static constexpr T f1() { return 0; }
+  static constexpr T f2() { return 0; }
+};
+
+int main() {
+  CreateSpecialization::f1();
+
+  // Don't emit coverage mapping info for functions in dependent contexts.
+  //
+  // E.g we never fully instantiate CreateSpecialization::f2(), so there
+  // should be no mapping for it.
+
+  return 0;
+}
+
+// MSABI: main:
+// MSABI-NEXT:   File 0, [[@LINE-12]]:12 -> [[@LINE-3]]:2 = #0
+// MSABI-NEXT: ?f1@?$CreateSpecialization@H$0A@@@SAHXZ:
+// MSABI-NEXT:   File 0, [[@LINE-18]]:27 -> [[@LINE-18]]:40 = #0
+
+// ITANIUM: main:
+// ITANIUM-NEXT:   File 0, [[@LINE-17]]:12 -> [[@LINE-8]]:2 = #0
+// ITANIUM-NEXT: _ZN20CreateSpecializationIiLi0EE2f1Ev:
+// ITANIUM-NEXT:   File 0, [[@LINE-23]]:27 -> [[@LINE-23]]:40 = #0
Index: lib/CodeGen/ModuleBuilder.cpp
===
--- lib/CodeGen/ModuleBuilder.cpp
+++ lib/CodeGen/ModuleBuilder.cpp
@@ -197,7 +197,8 @@
   // 

[PATCH] D31562: [coroutines] Fix building of new/delete expressions when get_return_object_on_allocation_failure() is present.

2017-04-17 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF updated this revision to Diff 95511.
EricWF added a comment.

- Update so it merges against master.


https://reviews.llvm.org/D31562

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaCoroutine.cpp
  test/CodeGenCoroutines/coro-alloc.cpp
  test/SemaCXX/coroutines.cpp

Index: test/SemaCXX/coroutines.cpp
===
--- test/SemaCXX/coroutines.cpp
+++ test/SemaCXX/coroutines.cpp
@@ -654,6 +654,18 @@
   co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
 }
 
+namespace std {
+  struct nothrow_t {};
+  constexpr nothrow_t nothrow = {};
+}
+
+using SizeT = decltype(sizeof(int));
+
+void* operator new(SizeT __sz, const std::nothrow_t&) noexcept;
+void  operator delete(void* __p, const std::nothrow_t&) noexcept;
+
+
+
 struct promise_on_alloc_failure_tag {};
 
 template<>
@@ -694,3 +706,43 @@
 }
 template coro dependent_private_alloc_failure_handler(bad_promise_11);
 // expected-note@-1 {{requested here}}
+
+struct bad_promise_12 {
+  coro get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  void unhandled_exception();
+  void return_void();
+  static coro get_return_object_on_allocation_failure();
+
+  static void* operator new(SizeT);
+  // expected-error@-1 2 {{'operator new' is required to have a non-throwing noexcept specification when the promise type declares 'get_return_object_on_allocation_failure()'}}
+};
+coro throwing_in_class_new() { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
+  co_return;
+}
+
+template 
+coro dependent_throwing_in_class_new(T) { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
+   co_return;
+}
+template coro dependent_throwing_in_class_new(bad_promise_12); // expected-note {{requested here}}
+
+
+struct good_promise_13 {
+  coro get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  void unhandled_exception();
+  void return_void();
+  static coro get_return_object_on_allocation_failure();
+};
+coro uses_nothrow_new() {
+  co_return;
+}
+
+template 
+coro dependent_uses_nothrow_new(T) {
+   co_return;
+}
+template coro dependent_uses_nothrow_new(good_promise_13);
Index: test/CodeGenCoroutines/coro-alloc.cpp
===
--- test/CodeGenCoroutines/coro-alloc.cpp
+++ test/CodeGenCoroutines/coro-alloc.cpp
@@ -21,8 +21,19 @@
   coroutine_handle(coroutine_handle) {}
 };
 
-}
-}
+} // end namespace experimental
+
+struct nothrow_t {};
+constexpr nothrow_t nothrow = {};
+
+} // end namespace std
+
+// Required when get_return_object_on_allocation_failure() is defined by
+// the promise.
+using SizeT = decltype(sizeof(int));
+void* operator new(SizeT __sz, const std::nothrow_t&) noexcept;
+void  operator delete(void* __p, const std::nothrow_t&) noexcept;
+
 
 struct suspend_always {
   bool await_ready() { return false; }
@@ -147,7 +158,7 @@
 extern "C" int f4(promise_on_alloc_failure_tag) {
   // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
   // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
-  // CHECK: %[[MEM:.+]] = call i8* @_Znwm(i64 %[[SIZE]])
+  // CHECK: %[[MEM:.+]] = call i8* @_ZnwmRKSt9nothrow_t(i64 %[[SIZE]], %"struct.std::nothrow_t"* dereferenceable(1) @_ZStL7nothrow)
   // CHECK: %[[OK:.+]] = icmp ne i8* %[[MEM]], null
   // CHECK: br i1 %[[OK]], label %[[OKBB:.+]], label %[[ERRBB:.+]]
 
Index: lib/Sema/SemaCoroutine.cpp
===
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -454,7 +454,7 @@
  /*IsImplicit*/ true);
 Suspend = S.ActOnFinishFullExpr(Suspend.get());
 if (Suspend.isInvalid()) {
-  S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
+  S.Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
   << ((Name == "initial_suspend") ? 0 : 1);
   S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
   return StmtError();
@@ -660,6 +660,39 @@
   return Res;
 }
 
+/// Look up the std::nothrow object.
+static Expr *buildStdNoThrowDeclRef(Sema , SourceLocation Loc) {
+  NamespaceDecl *Std = S.getStdNamespace();
+  assert(Std && "Should already be diagnosed");
+
+  LookupResult Result(S, ().get("nothrow"), Loc,
+  Sema::LookupOrdinaryName);
+  if (!S.LookupQualifiedName(Result, Std)) {
+// FIXME:  should have been included already.
+// If we require it to include  then this diagnostic is no longer
+// needed.
+S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
+return nullptr;
+  }
+
+  // FIXME: Mark the variable as ODR used. This currently does not work
+  // likely due to the scope at in which this function is called.
+  auto *VD = Result.getAsSingle();
+  if (!VD) {
+

[PATCH] D31487: [coroutines] Fix rebuilding of implicit and dependent coroutine statements.

2017-04-17 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF closed this revision.
EricWF added a comment.

Woops, I've been updating the wrong patch. These updates should have been for 
https://reviews.llvm.org/D31562.


https://reviews.llvm.org/D31487



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


[PATCH] D31562: [coroutines] Fix building of new/delete expressions when get_return_object_on_allocation_failure() is present.

2017-04-17 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF reopened this revision.
EricWF added a comment.
This revision is now accepted and ready to land.

Re-opening since the last commit had to be reverted.


https://reviews.llvm.org/D31562



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


r300515 - Fix mishandling of escaped newlines followed by newlines or nuls.

2017-04-17 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Mon Apr 17 18:44:51 2017
New Revision: 300515

URL: http://llvm.org/viewvc/llvm-project?rev=300515=rev
Log:
Fix mishandling of escaped newlines followed by newlines or nuls.

Previously, if an escaped newline was followed by a newline or a nul, we'd lex
the escaped newline as a bogus space character. This led to a bunch of
different broken corner cases:

For the pattern "\\\n\0#", we would then have a (horizontal) space whose
spelling ends in a newline, and would decide that the '#' is at the start of a
line, and incorrectly start preprocessing a directive in the middle of a
logical source line. If we were already in the middle of a directive, this
would result in our attempting to process multiple directives at the same time!
This resulted in crashes, asserts, and hangs on invalid input, as discovered by
fuzz-testing.

For the pattern "\\\n" at EOF (with an implicit following nul byte), we would
produce a bogus trailing space character with spelling "\\\n". This was mostly
harmless, but would lead to clang-format getting confused and misformatting in
rare cases. We now produce a trailing EOF token with spelling "\\\n",
consistent with our handling for other similar cases -- an escaped newline is
always part of the token containing the next character, if any.

For the pattern "\\\n\n", this was somewhat more benign, but would produce an
extraneous whitespace token to clients who care about preserving whitespace.
However, it turns out that our lexing for line comments was relying on this bug
due to an off-by-one error in its computation of the end of the comment, on the
slow path where the comment might contain escaped newlines.

Added:
cfe/trunk/test/Lexer/newline-nul.c   (with props)
Modified:
cfe/trunk/lib/Format/FormatTokenLexer.cpp
cfe/trunk/lib/Lex/Lexer.cpp
cfe/trunk/unittests/Format/FormatTestComments.cpp

Modified: cfe/trunk/lib/Format/FormatTokenLexer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/FormatTokenLexer.cpp?rev=300515=300514=300515=diff
==
--- cfe/trunk/lib/Format/FormatTokenLexer.cpp (original)
+++ cfe/trunk/lib/Format/FormatTokenLexer.cpp Mon Apr 17 18:44:51 2017
@@ -467,6 +467,9 @@ FormatToken *FormatTokenLexer::getNextTo
   if (pos >= 0 && Text[pos] == '\r')
 --pos;
   // See whether there is an odd number of '\' before this.
+  // FIXME: This is wrong. A '\' followed by a newline is always removed,
+  // regardless of whether there is another '\' before it.
+  // FIXME: Newlines can also be escaped by a '?' '?' '/' trigraph.
   unsigned count = 0;
   for (; pos >= 0; --pos, ++count)
 if (Text[pos] != '\\')

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=300515=300514=300515=diff
==
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Mon Apr 17 18:44:51 2017
@@ -1282,12 +1282,6 @@ Slash:
   Size += EscapedNewLineSize;
   Ptr  += EscapedNewLineSize;
 
-  // If the char that we finally got was a \n, then we must have had
-  // something like \.  We don't want to consume the
-  // second newline.
-  if (*Ptr == '\n' || *Ptr == '\r' || *Ptr == '\0')
-return ' ';
-
   // Use slow version to accumulate a correct size field.
   return getCharAndSizeSlow(Ptr, Size, Tok);
 }
@@ -1338,12 +1332,6 @@ Slash:
   Size += EscapedNewLineSize;
   Ptr  += EscapedNewLineSize;
 
-  // If the char that we finally got was a \n, then we must have had
-  // something like \.  We don't want to consume the
-  // second newline.
-  if (*Ptr == '\n' || *Ptr == '\r' || *Ptr == '\0')
-return ' ';
-
   // Use slow version to accumulate a correct size field.
   return getCharAndSizeSlowNoWarn(Ptr, Size, LangOpts);
 }
@@ -2070,8 +2058,11 @@ bool Lexer::SkipLineComment(Token 
   // Scan over the body of the comment.  The common case, when scanning, is 
that
   // the comment contains normal ascii characters with nothing interesting in
   // them.  As such, optimize for this case with the inner loop.
+  //
+  // This loop terminates with CurPtr pointing at the newline (or end of 
buffer)
+  // character that ends the line comment.
   char C;
-  do {
+  while (true) {
 C = *CurPtr;
 // Skip over characters in the fast loop.
 while (C != 0 &&// Potentially EOF.
@@ -2097,6 +2088,8 @@ bool Lexer::SkipLineComment(Token 
 break; // This is a newline, we're done.
 
   // If there was space between the backslash and newline, warn about it.
+  // FIXME: This warning is bogus if trigraphs are disabled and the line
+  // ended with '?' '?' '\\' '\n'.
   if (HasSpace && !isLexingRawMode())
 Diag(EscapePtr, diag::backslash_newline_space);
 }
@@ 

[PATCH] D31487: [coroutines] Fix rebuilding of implicit and dependent coroutine statements.

2017-04-17 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF updated this revision to Diff 95506.
EricWF added a comment.

- Update against trunk.


https://reviews.llvm.org/D31487

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaCoroutine.cpp
  test/CodeGenCoroutines/coro-alloc.cpp
  test/SemaCXX/coroutines.cpp

Index: test/SemaCXX/coroutines.cpp
===
--- test/SemaCXX/coroutines.cpp
+++ test/SemaCXX/coroutines.cpp
@@ -654,6 +654,18 @@
   co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
 }
 
+namespace std {
+  struct nothrow_t {};
+  constexpr nothrow_t nothrow = {};
+}
+
+using SizeT = decltype(sizeof(int));
+
+void* operator new(SizeT __sz, const std::nothrow_t&) noexcept;
+void  operator delete(void* __p, const std::nothrow_t&) noexcept;
+
+
+
 struct promise_on_alloc_failure_tag {};
 
 template<>
@@ -694,3 +706,43 @@
 }
 template coro dependent_private_alloc_failure_handler(bad_promise_11);
 // expected-note@-1 {{requested here}}
+
+struct bad_promise_12 {
+  coro get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  void unhandled_exception();
+  void return_void();
+  static coro get_return_object_on_allocation_failure();
+
+  static void* operator new(SizeT);
+  // expected-error@-1 2 {{'operator new' is required to have a non-throwing noexcept specification when the promise type declares 'get_return_object_on_allocation_failure()'}}
+};
+coro throwing_in_class_new() { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
+  co_return;
+}
+
+template 
+coro dependent_throwing_in_class_new(T) { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
+   co_return;
+}
+template coro dependent_throwing_in_class_new(bad_promise_12); // expected-note {{requested here}}
+
+
+struct good_promise_13 {
+  coro get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  void unhandled_exception();
+  void return_void();
+  static coro get_return_object_on_allocation_failure();
+};
+coro uses_nothrow_new() {
+  co_return;
+}
+
+template 
+coro dependent_uses_nothrow_new(T) {
+   co_return;
+}
+template coro dependent_uses_nothrow_new(good_promise_13);
Index: test/CodeGenCoroutines/coro-alloc.cpp
===
--- test/CodeGenCoroutines/coro-alloc.cpp
+++ test/CodeGenCoroutines/coro-alloc.cpp
@@ -21,8 +21,19 @@
   coroutine_handle(coroutine_handle) {}
 };
 
-}
-}
+} // end namespace experimental
+
+struct nothrow_t {};
+constexpr nothrow_t nothrow = {};
+
+} // end namespace std
+
+// Required when get_return_object_on_allocation_failure() is defined by
+// the promise.
+using SizeT = decltype(sizeof(int));
+void* operator new(SizeT __sz, const std::nothrow_t&) noexcept;
+void  operator delete(void* __p, const std::nothrow_t&) noexcept;
+
 
 struct suspend_always {
   bool await_ready() { return false; }
@@ -147,7 +158,7 @@
 extern "C" int f4(promise_on_alloc_failure_tag) {
   // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
   // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
-  // CHECK: %[[MEM:.+]] = call i8* @_Znwm(i64 %[[SIZE]])
+  // CHECK: %[[MEM:.+]] = call i8* @_ZnwmRKSt9nothrow_t(i64 %[[SIZE]], %"struct.std::nothrow_t"* dereferenceable(1) @_ZStL7nothrow)
   // CHECK: %[[OK:.+]] = icmp ne i8* %[[MEM]], null
   // CHECK: br i1 %[[OK]], label %[[OKBB:.+]], label %[[ERRBB:.+]]
 
Index: lib/Sema/SemaCoroutine.cpp
===
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -454,7 +454,7 @@
  /*IsImplicit*/ true);
 Suspend = S.ActOnFinishFullExpr(Suspend.get());
 if (Suspend.isInvalid()) {
-  S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
+  S.Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
   << ((Name == "initial_suspend") ? 0 : 1);
   S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
   return StmtError();
@@ -660,6 +660,39 @@
   return Res;
 }
 
+/// Look up the std::nothrow object.
+static Expr *buildStdNoThrowDeclRef(Sema , SourceLocation Loc) {
+  NamespaceDecl *Std = S.getStdNamespace();
+  assert(Std && "Should already be diagnosed");
+
+  LookupResult Result(S, ().get("nothrow"), Loc,
+  Sema::LookupOrdinaryName);
+  if (!S.LookupQualifiedName(Result, Std)) {
+// FIXME:  should have been included already.
+// If we require it to include  then this diagnostic is no longer
+// needed.
+S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
+return nullptr;
+  }
+
+  // FIXME: Mark the variable as ODR used. This currently does not work
+  // likely due to the scope at in which this function is called.
+  auto *VD = Result.getAsSingle();
+  if (!VD) {
+

[PATCH] D31487: [coroutines] Fix rebuilding of implicit and dependent coroutine statements.

2017-04-17 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF reopened this revision.
EricWF added a comment.
This revision is now accepted and ready to land.

re-opening because I had to revert the changes again. The tests are passing on 
my local machine but they're failing on the bots. I'm not exactly sure what's 
going on. Perhaps its UB caused by an uninitialized value? More investigation 
needed.


https://reviews.llvm.org/D31487



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


r300513 - Rename coroutine warning when unhandled_exception() is missing

2017-04-17 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Mon Apr 17 18:28:02 2017
New Revision: 300513

URL: http://llvm.org/viewvc/llvm-project?rev=300513=rev
Log:
Rename coroutine warning when unhandled_exception() is missing

Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
cfe/trunk/test/SemaCXX/coroutine-unhandled_exception-warning.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=300513=300512=300513=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Mon Apr 17 18:28:02 2017
@@ -36,7 +36,9 @@ def GNUCompoundLiteralInitializer : Diag
 def BitFieldConstantConversion : DiagGroup<"bitfield-constant-conversion">;
 def BitFieldEnumConversion : DiagGroup<"bitfield-enum-conversion">;
 def BitFieldWidth : DiagGroup<"bitfield-width">;
-def Coroutine : DiagGroup<"coroutine">;
+def CoroutineMissingUnhandledException :
+  DiagGroup<"coroutine-missing-unhandled-exception">;
+def Coroutine : DiagGroup<"coroutine", [CoroutineMissingUnhandledException]>;
 def ConstantConversion :
   DiagGroup<"constant-conversion", [ BitFieldConstantConversion ] >;
 def LiteralConversion : DiagGroup<"literal-conversion">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=300513=300512=300513=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Apr 17 18:28:02 
2017
@@ -8880,7 +8880,7 @@ def err_coroutine_promise_unhandled_exce
   "%0 is required to declare the member 'unhandled_exception()'">;
 def warn_coroutine_promise_unhandled_exception_required_with_exceptions : 
Warning<
   "%0 is required to declare the member 'unhandled_exception()' when 
exceptions are enabled">,
-  InGroup;
+  InGroup;
 def err_coroutine_promise_get_return_object_on_allocation_failure : Error<
   "%0: 'get_return_object_on_allocation_failure()' must be a static member 
function">;
 }

Modified: cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp?rev=300513=300512=300513=diff
==
--- cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp (original)
+++ cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp Mon Apr 17 18:28:02 2017
@@ -1,4 +1,6 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 
-emit-llvm %s -o - -disable-llvm-passes | FileCheck %s
+// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 
\
+// RUN:-Wno-coroutine-missing-unhandled-exception -emit-llvm %s -o - 
-disable-llvm-passes \
+// RUN:   | FileCheck %s
 
 namespace std {
 namespace experimental {
@@ -133,7 +135,7 @@ struct promise_on_alloc_failure_tag {};
 template<>
 struct std::experimental::coroutine_traits {
   struct promise_type {
-int get_return_object() {}
+int get_return_object() { return 0; }
 suspend_always initial_suspend() { return {}; }
 suspend_always final_suspend() { return {}; }
 void return_void() {}

Modified: cfe/trunk/test/SemaCXX/coroutine-unhandled_exception-warning.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/coroutine-unhandled_exception-warning.cpp?rev=300513=300512=300513=diff
==
--- cfe/trunk/test/SemaCXX/coroutine-unhandled_exception-warning.cpp (original)
+++ cfe/trunk/test/SemaCXX/coroutine-unhandled_exception-warning.cpp Mon Apr 17 
18:28:02 2017
@@ -1,4 +1,11 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts 
-fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks 
-Wno-unreachable-code -Wno-unused-value
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts \
+// RUN:-fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify \
+// RUN:-fblocks -Wno-unreachable-code -Wno-unused-value
+
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++14 -fcoroutines-ts \
+// RUN:-fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify \
+// RUN:-fblocks -Wno-unreachable-code -Wno-unused-value \
+// RUN:-DDISABLE_WARNING -Wno-coroutine-missing-unhandled-exception
 
 #if __has_feature(cxx_exceptions)
 #error This test requires exceptions be disabled
@@ -19,6 +26,12 @@ struct promise_void {
 template 
 struct std::experimental::coroutine_traits { using promise_type = 

Re: r300443 - Address http://bugs.llvm.org/pr30994 so that a non-friend can properly replace a friend, and a visible friend can properly replace an invisible friend but not vice verse, and definitions

2017-04-17 Thread Richard Smith via cfe-commits
On 17 April 2017 at 14:41, Vassil Vassilev  wrote:

> + Richard
>
> Thanks for the example. We've seen similar issue with inlines (without the
> reverted patch). My guess this patch exposed it.
>
> It is not clear to me why we think the declaration is a definition there...
>

Well, the declaration is a definition. It's definitely odd that we have a
note pointing to an inline definition and claiming it's non-inline; I'd
guess the source location and the "not inline" information are taken from
two different declarations that are implicitly expected to be consistent.
But I don't know why redeclaration lookup in the second module would ever
find a non-inline declaration.


> On 17/04/17 23:10, Benjamin Kramer via cfe-commits wrote:
>
> This broke our internal build of libc++ with modules. Reduced test
> case attached, courtesy of Richard Smith!
>
> With your patch it doesn't compiler anymore:
> While building module 'x':
> In file included from :2:
> In file included from ./c.h:1:
> ./a.h:3:32: error: inline declaration of 'f' follows non-inline definition
> template inline void f() {}
>^
> ./a.h:3:32: note: previous definition is here
> template inline void f() {}
>
>
> I reverted this change in r300497.
>
> On Mon, Apr 17, 2017 at 10:51 AM, Yaron Keren via 
> cfe-commits  wrote:
>
> Author: yrnkrn
> Date: Mon Apr 17 03:51:20 2017
> New Revision: 300443
>
> URL: http://llvm.org/viewvc/llvm-project?rev=300443=rev
> Log:
> Address http://bugs.llvm.org/pr30994 so that a non-friend can properly 
> replace a friend, and a visible friend can properly replace an invisible 
> friend but not vice verse, and definitions are not replaced. This fixes the 
> two FIXME in SemaTemplate/friend-template.cpp.
>
> The code implements Richard Smith suggestion in comment 3 of the PR.
>
> reviewer: Vassil Vassilev
>
> Differential Revision: https://reviews.llvm.org/D31540
>
>
> Modified:
> cfe/trunk/include/clang/AST/DeclBase.h
> cfe/trunk/lib/AST/Decl.cpp
> cfe/trunk/lib/AST/DeclBase.cpp
> cfe/trunk/test/SemaTemplate/friend-template.cpp
>
> Modified: cfe/trunk/include/clang/AST/DeclBase.h
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=300443=300442=300443=diff
> ==
> --- cfe/trunk/include/clang/AST/DeclBase.h (original)
> +++ cfe/trunk/include/clang/AST/DeclBase.h Mon Apr 17 03:51:20 2017
> @@ -417,6 +417,8 @@ public:
>  return const_cast(this)->getTranslationUnitDecl();
>}
>
> +  bool isThisDeclarationADefinition() const;
> +
>bool isInAnonymousNamespace() const;
>
>bool isInStdNamespace() const;
>
> Modified: cfe/trunk/lib/AST/Decl.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=300443=300442=300443=diff
> ==
> --- cfe/trunk/lib/AST/Decl.cpp (original)
> +++ cfe/trunk/lib/AST/Decl.cpp Mon Apr 17 03:51:20 2017
> @@ -1536,6 +1536,10 @@ bool NamedDecl::declarationReplaces(Name
>if (isa(this))
>  return false;
>
> +  if (getFriendObjectKind() > OldD->getFriendObjectKind() &&
> +  !isThisDeclarationADefinition())
> +return false;
> +
>// For parameters, pick the newer one. This is either an error or (in
>// Objective-C) permitted as an extension.
>if (isa(this))
>
> Modified: cfe/trunk/lib/AST/DeclBase.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=300443=300442=300443=diff
> ==
> --- cfe/trunk/lib/AST/DeclBase.cpp (original)
> +++ cfe/trunk/lib/AST/DeclBase.cpp Mon Apr 17 03:51:20 2017
> @@ -861,6 +861,21 @@ const FunctionType *Decl::getFunctionTyp
>return Ty->getAs();
>  }
>
> +bool Decl::isThisDeclarationADefinition() const {
> +  if (auto *TD = dyn_cast(this))
> +return TD->isThisDeclarationADefinition();
> +  if (auto *FD = dyn_cast(this))
> +return FD->isThisDeclarationADefinition();
> +  if (auto *VD = dyn_cast(this))
> +return VD->isThisDeclarationADefinition();
> +  if (auto *CTD = dyn_cast(this))
> +return CTD->isThisDeclarationADefinition();
> +  if (auto *FTD = dyn_cast(this))
> +return FTD->isThisDeclarationADefinition();
> +  if (auto *VTD = dyn_cast(this))
> +return VTD->isThisDeclarationADefinition();
> +  return false;
> +}
>
>  /// Starting at a given context (a Decl or DeclContext), look for a
>  /// code context that is not a closure (a lambda, block, etc.).
>
> Modified: cfe/trunk/test/SemaTemplate/friend-template.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend-template.cpp?rev=300443=300442=300443=diff
> ==
> --- cfe/trunk/test/SemaTemplate/friend-template.cpp 

[PATCH] D31778: [Modules] Implement ODR-like semantics for tag types in C/ObjC

2017-04-17 Thread Bruno Cardoso Lopes via Phabricator via cfe-commits
bruno added a comment.

Ping!


https://reviews.llvm.org/D31778



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


r300511 - Revert r300504 - [coroutines] Fix rebuilding of implicit and dependent coroutine statements.

2017-04-17 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Mon Apr 17 17:40:44 2017
New Revision: 300511

URL: http://llvm.org/viewvc/llvm-project?rev=300511=rev
Log:
Revert r300504 - [coroutines] Fix rebuilding of implicit and dependent 
coroutine statements.

I have no idea what's happening here. The tests that fail on all of the bots
pass on my machine. Further investigation needed.

Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
cfe/trunk/test/SemaCXX/coroutines.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=300511=300510=300511=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Apr 17 17:40:44 
2017
@@ -8854,11 +8854,6 @@ def err_coroutine_invalid_func_context :
 def err_implied_coroutine_type_not_found : Error<
   "%0 type was not found; include  before defining "
   "a coroutine">;
-def err_implicit_coroutine_std_nothrow_type_not_found : Error<
-  "std::nothrow was not found; include  before defining a coroutine which 
"
-  "uses get_return_object_on_allocation_failure()">;
-def err_malformed_std_nothrow : Error<
-  "std::nothrow must be a valid variable declaration">;
 def err_malformed_std_coroutine_handle : Error<
   "std::experimental::coroutine_handle must be a class template">;
 def err_coroutine_handle_missing_member : Error<
@@ -8878,7 +8873,7 @@ def err_coroutine_promise_return_ill_for
   "%0 declares both 'return_value' and 'return_void'">;
 def note_coroutine_promise_implicit_await_transform_required_here : Note<
   "call to 'await_transform' implicitly required by 'co_await' here">;
-def note_coroutine_promise_suspend_implicitly_required : Note<
+def note_coroutine_promise_call_implicitly_required : Note<
   "call to '%select{initial_suspend|final_suspend}0' implicitly "
   "required by the %select{initial suspend point|final suspend point}0">;
 def err_coroutine_promise_unhandled_exception_required : Error<
@@ -,11 +8883,6 @@ def warn_coroutine_promise_unhandled_exc
   InGroup;
 def err_coroutine_promise_get_return_object_on_allocation_failure : Error<
   "%0: 'get_return_object_on_allocation_failure()' must be a static member 
function">;
-def err_coroutine_promise_new_requires_nothrow : Error<
-  "%0 is required to have a non-throwing noexcept specification when the 
promise "
-   "type declares 'get_return_object_on_allocation_failure()'">;
-def note_coroutine_promise_call_implicitly_required : Note<
-  "call to %0 implicitly required by coroutine function here">;
 }
 
 let CategoryName = "Documentation Issue" in {

Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=300511=300510=300511=diff
==
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Mon Apr 17 17:40:44 2017
@@ -454,7 +454,7 @@ static bool actOnCoroutineBodyStart(Sema
  /*IsImplicit*/ true);
 Suspend = S.ActOnFinishFullExpr(Suspend.get());
 if (Suspend.isInvalid()) {
-  S.Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
+  S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
   << ((Name == "initial_suspend") ? 0 : 1);
   S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
   return StmtError();
@@ -660,39 +660,6 @@ StmtResult Sema::BuildCoreturnStmt(Sourc
   return Res;
 }
 
-/// Look up the std::nothrow object.
-static Expr *buildStdNoThrowDeclRef(Sema , SourceLocation Loc) {
-  NamespaceDecl *Std = S.getStdNamespace();
-  assert(Std && "Should already be diagnosed");
-
-  LookupResult Result(S, ().get("nothrow"), Loc,
-  Sema::LookupOrdinaryName);
-  if (!S.LookupQualifiedName(Result, Std)) {
-// FIXME:  should have been included already.
-// If we require it to include  then this diagnostic is no longer
-// needed.
-S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
-return nullptr;
-  }
-
-  // FIXME: Mark the variable as ODR used. This currently does not work
-  // likely due to the scope at in which this function is called.
-  auto *VD = Result.getAsSingle();
-  if (!VD) {
-Result.suppressDiagnostics();
-// We found something weird. Complain about the first thing we found.
-NamedDecl *Found = *Result.begin();
-S.Diag(Found->getLocation(), diag::err_malformed_std_nothrow);
-return nullptr;
-  }
-
-  ExprResult DR = S.BuildDeclRefExpr(VD, VD->getType(), VK_LValue, Loc);
-  if (DR.isInvalid())
-return nullptr;
-
-  return DR.get();
-}
-
 // Find an appropriate delete for 

[libcxx] r300510 - Work around GCC 4.9 bug regarding default initialization of const variables

2017-04-17 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Mon Apr 17 17:32:02 2017
New Revision: 300510

URL: http://llvm.org/viewvc/llvm-project?rev=300510=rev
Log:
Work around GCC 4.9 bug regarding default initialization of const variables

Modified:
libcxx/trunk/include/memory

Modified: libcxx/trunk/include/memory
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=300510=300509=300510=diff
==
--- libcxx/trunk/include/memory (original)
+++ libcxx/trunk/include/memory Mon Apr 17 17:32:02 2017
@@ -2079,17 +2079,12 @@ struct __compressed_pair_elem {
   typedef const _Tp& const_reference;
 
 #ifndef _LIBCPP_CXX03_LANG
-  template , _Dummy>::value
->::type
-  >
-  _LIBCPP_CONSTEXPR __compressed_pair_elem()
-  _NOEXCEPT_(is_nothrow_default_constructible<_Tp>::value)
-: __value_() {}
+  constexpr __compressed_pair_elem() : __value_() {}
 
   template ::value>::type>
-  _LIBCPP_CONSTEXPR explicit
+  !is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
+  >::type>
+  constexpr explicit
   __compressed_pair_elem(_Up&& __u)
   : __value_(_VSTD::forward<_Up>(__u)){};
 
@@ -2118,11 +2113,12 @@ struct __compressed_pair_elem<_Tp, _Idx,
   typedef _Tp __value_type;
 
 #ifndef _LIBCPP_CXX03_LANG
-  _LIBCPP_CONSTEXPR __compressed_pair_elem() = default;
+  constexpr __compressed_pair_elem() = default;
 
   template ::value>::type>
-  _LIBCPP_CONSTEXPR explicit
+!is_same<__compressed_pair_elem, typename decay<_Up>::type>::value
+  >::type>
+  constexpr explicit
   __compressed_pair_elem(_Up&& __u)
   : __value_type(_VSTD::forward<_Up>(__u)){};
 
@@ -2161,8 +2157,14 @@ class __compressed_pair : private __comp
 
 public:
 #ifndef _LIBCPP_CXX03_LANG
+  template , _Dummy>::value &&
+  __dependent_type, _Dummy>::value
+  >::type
+  >
   _LIBCPP_INLINE_VISIBILITY
-  __compressed_pair() = default;
+  constexpr __compressed_pair() {}
 
   template ::type,
__compressed_pair>::value,


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


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-17 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc added a comment.

In https://reviews.llvm.org/D32064#728629, @rnk wrote:

> In https://reviews.llvm.org/D32064#726861, @pcc wrote:
>
> > I think it would be better to move this logic to the driver and have it 
> > pass in an `-mllvm` flag. The sanitizer passes should really be taking no 
> > arguments in the constructor like the other passes, so I don't want us to 
> > add another argument here.
>
>
> That seems like the opposite of the direction we've been moving, though. 
> cl::opt flags can't appear twice, and this means one process can't do two 
> asan compilations in two LLVMContexts in parallel with different settings.


Yes, but adding an argument is also the wrong direction. This information 
should really be passed either via the module (e.g. module flags or attributes) 
or the TargetMachine. If we aren't going to do that, we might as well pass it 
via `-mllvm`, as it is simpler.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



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


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-17 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added inline comments.



Comment at: lib/Driver/SanitizerArgs.cpp:636
+  case llvm::Triple::COFF:
+return DataSections;
+  case llvm::Triple::ELF:

eugenis wrote:
> rnk wrote:
> > We can return true for COFF here. By adding a comdat during asan 
> > instrumentation, we effectively implement -fdata-sections ourselves. If the 
> > user really wanted -fno-data-sections for some reason, they're out of luck 
> > right now.
> What do you mean by "out of luck", will it break compilation?
> Because the point of this change is not to enable data-sections unless asked 
> by the user. Data sections greatly inflate ELF object file size (not sure how 
> big is the effect on COFF) and we should not do that by default.
By "out of luck", I was thinking about users who might do crazy things like 
take label differences between globals and assume that they are laid out 
consecutively in the original source file order. I wasn't thinking about object 
file size.

The size increase for COFF is probably comparable, so I guess I agree, this is 
reasonable behavior. I think Chromium explicitly passes `/Gw`, which is 
equivalent to `-fdata-sections`. We basically don't support non-integrated as 
on Windows at this point. We've extended the assembler a number of times 
already.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



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


r300509 - [ubsan] Skip null checks if they are constant-folded away

2017-04-17 Thread Vedant Kumar via cfe-commits
Author: vedantk
Date: Mon Apr 17 17:26:10 2017
New Revision: 300509

URL: http://llvm.org/viewvc/llvm-project?rev=300509=rev
Log:
[ubsan] Skip null checks if they are constant-folded away

The IR builder can constant-fold null checks if the pointer operand
points to a constant. If the "is-non-null" check is folded away to
"true", don't emit the null check + branch.

Testing: check-clang, check-ubsan.

This slightly reduces the amount of null checks we emit when compiling
X86ISelLowering.cpp. Here are the numbers from patched/unpatched clangs
based on r300371.

  -
  | Setup  | # of null checks |
  -
  | unpatched, -O0 |25251 |
  | patched, -O0   |23925 | (-5.3%)
  -

Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=300509=300508=300509=diff
==
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Apr 17 17:26:10 2017
@@ -568,15 +568,23 @@ void CodeGenFunction::EmitTypeCheck(Type
 // The glvalue must not be an empty glvalue.
 llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr);
 
-if (AllowNullPointers) {
-  // When performing pointer casts, it's OK if the value is null.
-  // Skip the remaining checks in that case.
-  Done = createBasicBlock("null");
-  llvm::BasicBlock *Rest = createBasicBlock("not.null");
-  Builder.CreateCondBr(IsNonNull, Rest, Done);
-  EmitBlock(Rest);
-} else {
-  Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null));
+// The IR builder can constant-fold the null check if the pointer points to
+// a constant.
+bool PtrIsNonNull =
+IsNonNull == llvm::ConstantInt::getTrue(getLLVMContext());
+
+// Skip the null check if the pointer is known to be non-null.
+if (!PtrIsNonNull) {
+  if (AllowNullPointers) {
+// When performing pointer casts, it's OK if the value is null.
+// Skip the remaining checks in that case.
+Done = createBasicBlock("null");
+llvm::BasicBlock *Rest = createBasicBlock("not.null");
+Builder.CreateCondBr(IsNonNull, Rest, Done);
+EmitBlock(Rest);
+  } else {
+Checks.push_back(std::make_pair(IsNonNull, SanitizerKind::Null));
+  }
 }
   }
 

Modified: cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp?rev=300509=300508=300509=diff
==
--- cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp Mon Apr 17 17:26:10 2017
@@ -10,6 +10,8 @@ void load_non_null_pointers() {
   int arr[1];
   arr[0] = arr[0];
 
+  char c = "foo"[0];
+
   // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize
   // CHECK: ret void
 }


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


r300508 - [ubsan] Skip null checks on pointers to the start of an alloca

2017-04-17 Thread Vedant Kumar via cfe-commits
Author: vedantk
Date: Mon Apr 17 17:26:07 2017
New Revision: 300508

URL: http://llvm.org/viewvc/llvm-project?rev=300508=rev
Log:
[ubsan] Skip null checks on pointers to the start of an alloca

Pointers to the start of an alloca are non-null, so we don't need to
emit runtime null checks for them.

Testing: check-clang, check-ubsan.

This significantly reduces the amount of null checks we emit when
compiling X86ISelLowering.cpp. Here are the numbers from patched /
unpatched clangs based on r300371.

  -
  | Setup  | # of null checks |
  -
  | unpatched, -O0 |45439 |
  | patched, -O0   |25251 | (-44.4%)
  -

Modified:
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=300508=300507=300508=diff
==
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Apr 17 17:26:07 2017
@@ -533,6 +533,15 @@ bool CodeGenFunction::sanitizePerformTyp
  SanOpts.has(SanitizerKind::Vptr);
 }
 
+/// Check if a runtime null check for \p Ptr can be omitted.
+static bool canOmitPointerNullCheck(llvm::Value *Ptr) {
+  // Note: do not perform any constant-folding in this function. That is best
+  // left to the IR builder.
+
+  // Pointers to alloca'd memory are non-null.
+  return isa(Ptr->stripPointerCastsNoFollowAliases());
+}
+
 void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc,
 llvm::Value *Ptr, QualType Ty,
 CharUnits Alignment,
@@ -554,7 +563,8 @@ void CodeGenFunction::EmitTypeCheck(Type
   bool AllowNullPointers = TCK == TCK_DowncastPointer || TCK == TCK_Upcast ||
TCK == TCK_UpcastToVirtualBase;
   if ((SanOpts.has(SanitizerKind::Null) || AllowNullPointers) &&
-  !SkippedChecks.has(SanitizerKind::Null)) {
+  !SkippedChecks.has(SanitizerKind::Null) &&
+  !canOmitPointerNullCheck(Ptr)) {
 // The glvalue must not be an empty glvalue.
 llvm::Value *IsNonNull = Builder.CreateIsNotNull(Ptr);
 

Modified: cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp?rev=300508=300507=300508=diff
==
--- cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/ubsan-suppress-checks.cpp Mon Apr 17 17:26:07 2017
@@ -2,6 +2,18 @@
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s 
-fsanitize=null | FileCheck %s --check-prefixes=CHECK,NULL
 // RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin10 -emit-llvm -o - %s 
-fsanitize=alignment,null -DCHECK_LAMBDA | FileCheck %s --check-prefixes=LAMBDA
 
+// CHECK-LABEL: define void @_Z22load_non_null_pointersv
+void load_non_null_pointers() {
+  int var;
+  var = *
+
+  int arr[1];
+  arr[0] = arr[0];
+
+  // CHECK-NOT: icmp ne {{.*}}, null, !nosanitize
+  // CHECK: ret void
+}
+
 struct A {
   int foo;
 
@@ -29,8 +41,7 @@ struct A {
 };
 f();
 
-// LAMBDA: icmp ne %class.anon* %[[FUNCVAR:.*]], null, !nosanitize
-// LAMBDA: %[[LAMBDAINT:[0-9]+]] = ptrtoint %class.anon* %[[FUNCVAR]] to 
i64, !nosanitize
+// LAMBDA: %[[LAMBDAINT:[0-9]+]] = ptrtoint %class.anon* %[[FUNCVAR:.*]] 
to i64, !nosanitize
 // LAMBDA: and i64 %[[LAMBDAINT]], 7, !nosanitize
 // LAMBDA: call void @__ubsan_handle_type_mismatch
 
@@ -127,8 +138,8 @@ struct A {
 struct B {
   operator A*() const { return nullptr; }
 
-  // CHECK-LABEL: define linkonce_odr i32 @_ZN1B11load_memberEv
-  static int load_member() {
+  // CHECK-LABEL: define linkonce_odr i32 @_ZN1B11load_memberEPS_
+  static int load_member(B *bp) {
 // Check  before converting it to an A*.
 // CHECK: call void @__ubsan_handle_type_mismatch
 //
@@ -136,8 +147,7 @@ struct B {
 // NULL: call void @__ubsan_handle_type_mismatch
 //
 // CHECK-NOT: call void @__ubsan_handle_type_mismatch
-B b;
-return static_cast(b)->load_member();
+return static_cast(*bp)->load_member();
 // CHECK: ret i32
   }
 };
@@ -210,7 +220,7 @@ void force_irgen() {
   A::call_through_reference(*a);
   A::call_through_pointer(a);
 
-  B::load_member();
+  B::load_member(nullptr);
 
   Base *b = new Derived;
   b->load_member_1();
@@ -218,4 +228,6 @@ void force_irgen() {
   Derived *d;
   d->load_member_2();
   d->load_member_3();
+
+  load_non_null_pointers();
 }


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


r300504 - [coroutines] Fix rebuilding of implicit and dependent coroutine statements.

2017-04-17 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Mon Apr 17 17:06:13 2017
New Revision: 300504

URL: http://llvm.org/viewvc/llvm-project?rev=300504=rev
Log:
[coroutines] Fix rebuilding of implicit and dependent coroutine statements.

Summary:
Certain implicitly generated coroutine statements, such as the calls to 
'return_value()' or `return_void()` or 
`get_return_object_on_allocation_failure()`, cannot be built until the promise 
type is no longer dependent. This means they are not built until after the 
coroutine body statement has been transformed.

This patch fixes an issue where these statements would never be built for 
coroutine templates.

It also fixes a small issue where diagnostics about 
`get_return_object_on_allocation_failure()` were incorrectly suppressed. 

Reviewers: rsmith, majnemer, GorNishanov, aaron.ballman

Reviewed By: GorNishanov

Subscribers: cfe-commits

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

Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaCoroutine.cpp
cfe/trunk/test/CodeGenCoroutines/coro-alloc.cpp
cfe/trunk/test/SemaCXX/coroutines.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=300504=300503=300504=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Apr 17 17:06:13 
2017
@@ -8854,6 +8854,11 @@ def err_coroutine_invalid_func_context :
 def err_implied_coroutine_type_not_found : Error<
   "%0 type was not found; include  before defining "
   "a coroutine">;
+def err_implicit_coroutine_std_nothrow_type_not_found : Error<
+  "std::nothrow was not found; include  before defining a coroutine which 
"
+  "uses get_return_object_on_allocation_failure()">;
+def err_malformed_std_nothrow : Error<
+  "std::nothrow must be a valid variable declaration">;
 def err_malformed_std_coroutine_handle : Error<
   "std::experimental::coroutine_handle must be a class template">;
 def err_coroutine_handle_missing_member : Error<
@@ -8873,7 +8878,7 @@ def err_coroutine_promise_return_ill_for
   "%0 declares both 'return_value' and 'return_void'">;
 def note_coroutine_promise_implicit_await_transform_required_here : Note<
   "call to 'await_transform' implicitly required by 'co_await' here">;
-def note_coroutine_promise_call_implicitly_required : Note<
+def note_coroutine_promise_suspend_implicitly_required : Note<
   "call to '%select{initial_suspend|final_suspend}0' implicitly "
   "required by the %select{initial suspend point|final suspend point}0">;
 def err_coroutine_promise_unhandled_exception_required : Error<
@@ -8883,6 +,11 @@ def warn_coroutine_promise_unhandled_exc
   InGroup;
 def err_coroutine_promise_get_return_object_on_allocation_failure : Error<
   "%0: 'get_return_object_on_allocation_failure()' must be a static member 
function">;
+def err_coroutine_promise_new_requires_nothrow : Error<
+  "%0 is required to have a non-throwing noexcept specification when the 
promise "
+   "type declares 'get_return_object_on_allocation_failure()'">;
+def note_coroutine_promise_call_implicitly_required : Note<
+  "call to %0 implicitly required by coroutine function here">;
 }
 
 let CategoryName = "Documentation Issue" in {

Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=300504=300503=300504=diff
==
--- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Mon Apr 17 17:06:13 2017
@@ -454,7 +454,7 @@ static bool actOnCoroutineBodyStart(Sema
  /*IsImplicit*/ true);
 Suspend = S.ActOnFinishFullExpr(Suspend.get());
 if (Suspend.isInvalid()) {
-  S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
+  S.Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
   << ((Name == "initial_suspend") ? 0 : 1);
   S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
   return StmtError();
@@ -660,6 +660,39 @@ StmtResult Sema::BuildCoreturnStmt(Sourc
   return Res;
 }
 
+/// Look up the std::nothrow object.
+static Expr *buildStdNoThrowDeclRef(Sema , SourceLocation Loc) {
+  NamespaceDecl *Std = S.getStdNamespace();
+  assert(Std && "Should already be diagnosed");
+
+  LookupResult Result(S, ().get("nothrow"), Loc,
+  Sema::LookupOrdinaryName);
+  if (!S.LookupQualifiedName(Result, Std)) {
+// FIXME:  should have been included already.
+// If we require it to include  then this diagnostic is no longer
+// needed.
+S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
+return nullptr;
+  }
+
+  // FIXME: Mark the variable as ODR used. This 

[PATCH] D31487: [coroutines] Fix rebuilding of implicit and dependent coroutine statements.

2017-04-17 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF updated this revision to Diff 95501.
EricWF added a comment.

- Upload new, hopefully correct, diff.


https://reviews.llvm.org/D31487

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaCoroutine.cpp
  test/CodeGenCoroutines/coro-alloc.cpp
  test/SemaCXX/coroutines.cpp

Index: test/SemaCXX/coroutines.cpp
===
--- test/SemaCXX/coroutines.cpp
+++ test/SemaCXX/coroutines.cpp
@@ -654,6 +654,18 @@
   co_return; //expected-note {{function is a coroutine due to use of 'co_return' here}}
 }
 
+namespace std {
+  struct nothrow_t {};
+  constexpr nothrow_t nothrow = {};
+}
+
+using SizeT = decltype(sizeof(int));
+
+void* operator new(SizeT __sz, const std::nothrow_t&) noexcept;
+void  operator delete(void* __p, const std::nothrow_t&) noexcept;
+
+
+
 struct promise_on_alloc_failure_tag {};
 
 template<>
@@ -694,3 +706,43 @@
 }
 template coro dependent_private_alloc_failure_handler(bad_promise_11);
 // expected-note@-1 {{requested here}}
+
+struct bad_promise_12 {
+  coro get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  void unhandled_exception();
+  void return_void();
+  static coro get_return_object_on_allocation_failure();
+
+  static void* operator new(SizeT);
+  // expected-error@-1 2 {{'operator new' is required to have a non-throwing noexcept specification when the promise type declares 'get_return_object_on_allocation_failure()'}}
+};
+coro throwing_in_class_new() { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
+  co_return;
+}
+
+template 
+coro dependent_throwing_in_class_new(T) { // expected-note {{call to 'operator new' implicitly required by coroutine function here}}
+   co_return;
+}
+template coro dependent_throwing_in_class_new(bad_promise_12); // expected-note {{requested here}}
+
+
+struct good_promise_13 {
+  coro get_return_object();
+  suspend_always initial_suspend();
+  suspend_always final_suspend();
+  void unhandled_exception();
+  void return_void();
+  static coro get_return_object_on_allocation_failure();
+};
+coro uses_nothrow_new() {
+  co_return;
+}
+
+template 
+coro dependent_uses_nothrow_new(T) {
+   co_return;
+}
+template coro dependent_uses_nothrow_new(good_promise_13);
Index: test/CodeGenCoroutines/coro-alloc.cpp
===
--- test/CodeGenCoroutines/coro-alloc.cpp
+++ test/CodeGenCoroutines/coro-alloc.cpp
@@ -19,8 +19,19 @@
   coroutine_handle(coroutine_handle) {}
 };
 
-}
-}
+} // end namespace experimental
+
+struct nothrow_t {};
+constexpr nothrow_t nothrow = {};
+
+} // end namespace std
+
+// Required when get_return_object_on_allocation_failure() is defined by
+// the promise.
+using SizeT = decltype(sizeof(int));
+void* operator new(SizeT __sz, const std::nothrow_t&) noexcept;
+void  operator delete(void* __p, const std::nothrow_t&) noexcept;
+
 
 struct suspend_always {
   bool await_ready() { return false; }
@@ -145,7 +156,7 @@
 extern "C" int f4(promise_on_alloc_failure_tag) {
   // CHECK: %[[ID:.+]] = call token @llvm.coro.id(i32 16
   // CHECK: %[[SIZE:.+]] = call i64 @llvm.coro.size.i64()
-  // CHECK: %[[MEM:.+]] = call i8* @_Znwm(i64 %[[SIZE]])
+  // CHECK: %[[MEM:.+]] = call i8* @_ZnwmRKSt9nothrow_t(i64 %[[SIZE]], %"struct.std::nothrow_t"* dereferenceable(1) @_ZStL7nothrow)
   // CHECK: %[[OK:.+]] = icmp ne i8* %[[MEM]], null
   // CHECK: br i1 %[[OK]], label %[[OKBB:.+]], label %[[ERRBB:.+]]
 
Index: lib/Sema/SemaCoroutine.cpp
===
--- lib/Sema/SemaCoroutine.cpp
+++ lib/Sema/SemaCoroutine.cpp
@@ -454,7 +454,7 @@
  /*IsImplicit*/ true);
 Suspend = S.ActOnFinishFullExpr(Suspend.get());
 if (Suspend.isInvalid()) {
-  S.Diag(Loc, diag::note_coroutine_promise_call_implicitly_required)
+  S.Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required)
   << ((Name == "initial_suspend") ? 0 : 1);
   S.Diag(KWLoc, diag::note_declared_coroutine_here) << Keyword;
   return StmtError();
@@ -660,6 +660,39 @@
   return Res;
 }
 
+/// Look up the std::nothrow object.
+static Expr *buildStdNoThrowDeclRef(Sema , SourceLocation Loc) {
+  NamespaceDecl *Std = S.getStdNamespace();
+  assert(Std && "Should already be diagnosed");
+
+  LookupResult Result(S, ().get("nothrow"), Loc,
+  Sema::LookupOrdinaryName);
+  if (!S.LookupQualifiedName(Result, Std)) {
+// FIXME:  should have been included already.
+// If we require it to include  then this diagnostic is no longer
+// needed.
+S.Diag(Loc, diag::err_implicit_coroutine_std_nothrow_type_not_found);
+return nullptr;
+  }
+
+  // FIXME: Mark the variable as ODR used. This currently does not work
+  // likely due to the scope at in which this function is called.
+  auto *VD = Result.getAsSingle();
+  if (!VD) {
+

[PATCH] D31542: [clang-tidy] Extend readability-container-size-empty to add comparisons to newly-constructed objects

2017-04-17 Thread Josh Zimmerman via Phabricator via cfe-commits
joshz updated this revision to Diff 95488.
joshz marked an inline comment as done.
joshz edited the summary of this revision.
joshz added a comment.

Resolved the bug, with a slightly modified version of Aaron's suggestion. (It 
will suggest parens for anything that wasn't just a DeclRefExpr, which may be a 
bit over-exuberant, but not as much as always suggesting them.)


Repository:
  rL LLVM

https://reviews.llvm.org/D31542

Files:
  clang-tidy/readability/ContainerSizeEmptyCheck.cpp
  test/clang-tidy/readability-container-size-empty.cpp

Index: test/clang-tidy/readability-container-size-empty.cpp
===
--- test/clang-tidy/readability-container-size-empty.cpp
+++ test/clang-tidy/readability-container-size-empty.cpp
@@ -3,6 +3,8 @@
 namespace std {
 template  struct vector {
   vector();
+  bool operator==(const vector& other) const;
+  bool operator!=(const vector& other) const;
   unsigned long size() const;
   bool empty() const;
 };
@@ -9,6 +11,11 @@
 
 template  struct basic_string {
   basic_string();
+  bool operator==(const basic_string& other) const;
+  bool operator!=(const basic_string& other) const;
+  bool operator==(const char *) const;
+  bool operator!=(const char *) const;
+  basic_string operator+(const basic_string& other) const;
   unsigned long size() const;
   bool empty() const;
 };
@@ -19,6 +26,8 @@
 inline namespace __v2 {
 template  struct set {
   set();
+  bool operator==(const set& other) const;
+  bool operator!=(const set& other) const;
   unsigned long size() const;
   bool empty() const;
 };
@@ -29,6 +38,8 @@
 template 
 class TemplatedContainer {
 public:
+  bool operator==(const TemplatedContainer& other) const;
+  bool operator!=(const TemplatedContainer& other) const;
   int size() const;
   bool empty() const;
 };
@@ -36,6 +47,8 @@
 template 
 class PrivateEmpty {
 public:
+  bool operator==(const PrivateEmpty& other) const;
+  bool operator!=(const PrivateEmpty& other) const;
   int size() const;
 private:
   bool empty() const;
@@ -54,6 +67,7 @@
 
 class Container {
 public:
+  bool operator==(const Container& other) const;
   int size() const;
   bool empty() const;
 };
@@ -75,9 +89,17 @@
 
 bool Container3::empty() const { return this->size() == 0; }
 
+class Container4 {
+public:
+  bool operator==(const Container4& rhs) const;
+  int size() const;
+  bool empty() const { return *this == Container4(); }
+};
+
 int main() {
   std::set intSet;
   std::string str;
+  std::string str2;
   std::wstring wstr;
   str.size() + 0;
   str.size() - 0;
@@ -87,24 +109,53 @@
 ;
   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness instead of 'size' [readability-container-size-empty]
   // CHECK-FIXES: {{^  }}if (intSet.empty()){{$}}
-  // CHECK-MESSAGES: :23:8: note: method 'set'::empty() defined here
+  // CHECK-MESSAGES: :32:8: note: method 'set'::empty() defined here
+  if (intSet == std::set())
+;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used to check for emptiness
+  // CHECK-FIXES: {{^  }}if (intSet.empty()){{$}}
+  // CHECK-MESSAGES: :32:8: note: method 'set'::empty() defined here
   if (str.size() == 0)
 ;
   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
   // CHECK-FIXES: {{^  }}if (str.empty()){{$}}
+  if ((str + str2).size() == 0)
+;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+  // CHECK-FIXES: {{^  }}if ((str + str2).empty()){{$}}
+  if (str == "")
+;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+  // CHECK-FIXES: {{^  }}if (str.empty()){{$}}
+  if (str + str2 == "")
+;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+  // CHECK-FIXES: {{^  }}if ((str + str2).empty()){{$}}
   if (wstr.size() == 0)
 ;
   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
   // CHECK-FIXES: {{^  }}if (wstr.empty()){{$}}
+  if (wstr == "")
+;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+  // CHECK-FIXES: {{^  }}if (wstr.empty()){{$}}
   std::vector vect;
   if (vect.size() == 0)
 ;
   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
   // CHECK-FIXES: {{^  }}if (vect.empty()){{$}}
+  if (vect == std::vector())
+;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+  // CHECK-FIXES: {{^  }}if (vect.empty()){{$}}
   if (vect.size() != 0)
 ;
   // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
   // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
+  if (vect != std::vector())
+;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: the 'empty' method should be used
+  // CHECK-FIXES: {{^  }}if (!vect.empty()){{$}}
   if (0 == vect.size())
 ;
   // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: the 'empty' method should 

[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-17 Thread Evgeniy Stepanov via Phabricator via cfe-commits
eugenis added inline comments.



Comment at: lib/Driver/SanitizerArgs.cpp:636
+  case llvm::Triple::COFF:
+return DataSections;
+  case llvm::Triple::ELF:

rnk wrote:
> We can return true for COFF here. By adding a comdat during asan 
> instrumentation, we effectively implement -fdata-sections ourselves. If the 
> user really wanted -fno-data-sections for some reason, they're out of luck 
> right now.
What do you mean by "out of luck", will it break compilation?
Because the point of this change is not to enable data-sections unless asked by 
the user. Data sections greatly inflate ELF object file size (not sure how big 
is the effect on COFF) and we should not do that by default.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



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


Re: r300443 - Address http://bugs.llvm.org/pr30994 so that a non-friend can properly replace a friend, and a visible friend can properly replace an invisible friend but not vice verse, and definitions

2017-04-17 Thread Vassil Vassilev via cfe-commits

+ Richard

Thanks for the example. We've seen similar issue with inlines (without 
the reverted patch). My guess this patch exposed it.


It is not clear to me why we think the declaration is a definition there...
On 17/04/17 23:10, Benjamin Kramer via cfe-commits wrote:

This broke our internal build of libc++ with modules. Reduced test
case attached, courtesy of Richard Smith!

With your patch it doesn't compiler anymore:
While building module 'x':
In file included from :2:
In file included from ./c.h:1:
./a.h:3:32: error: inline declaration of 'f' follows non-inline definition
template inline void f() {}
^
./a.h:3:32: note: previous definition is here
template inline void f() {}


I reverted this change in r300497.

On Mon, Apr 17, 2017 at 10:51 AM, Yaron Keren via cfe-commits
 wrote:

Author: yrnkrn
Date: Mon Apr 17 03:51:20 2017
New Revision: 300443

URL: http://llvm.org/viewvc/llvm-project?rev=300443=rev
Log:
Address http://bugs.llvm.org/pr30994 so that a non-friend can properly replace 
a friend, and a visible friend can properly replace an invisible friend but not 
vice verse, and definitions are not replaced. This fixes the two FIXME in 
SemaTemplate/friend-template.cpp.

The code implements Richard Smith suggestion in comment 3 of the PR.

reviewer: Vassil Vassilev

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


Modified:
 cfe/trunk/include/clang/AST/DeclBase.h
 cfe/trunk/lib/AST/Decl.cpp
 cfe/trunk/lib/AST/DeclBase.cpp
 cfe/trunk/test/SemaTemplate/friend-template.cpp

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=300443=300442=300443=diff
==
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Mon Apr 17 03:51:20 2017
@@ -417,6 +417,8 @@ public:
  return const_cast(this)->getTranslationUnitDecl();
}

+  bool isThisDeclarationADefinition() const;
+
bool isInAnonymousNamespace() const;

bool isInStdNamespace() const;

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=300443=300442=300443=diff
==
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon Apr 17 03:51:20 2017
@@ -1536,6 +1536,10 @@ bool NamedDecl::declarationReplaces(Name
if (isa(this))
  return false;

+  if (getFriendObjectKind() > OldD->getFriendObjectKind() &&
+  !isThisDeclarationADefinition())
+return false;
+
// For parameters, pick the newer one. This is either an error or (in
// Objective-C) permitted as an extension.
if (isa(this))

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=300443=300442=300443=diff
==
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Mon Apr 17 03:51:20 2017
@@ -861,6 +861,21 @@ const FunctionType *Decl::getFunctionTyp
return Ty->getAs();
  }

+bool Decl::isThisDeclarationADefinition() const {
+  if (auto *TD = dyn_cast(this))
+return TD->isThisDeclarationADefinition();
+  if (auto *FD = dyn_cast(this))
+return FD->isThisDeclarationADefinition();
+  if (auto *VD = dyn_cast(this))
+return VD->isThisDeclarationADefinition();
+  if (auto *CTD = dyn_cast(this))
+return CTD->isThisDeclarationADefinition();
+  if (auto *FTD = dyn_cast(this))
+return FTD->isThisDeclarationADefinition();
+  if (auto *VTD = dyn_cast(this))
+return VTD->isThisDeclarationADefinition();
+  return false;
+}

  /// Starting at a given context (a Decl or DeclContext), look for a
  /// code context that is not a closure (a lambda, block, etc.).

Modified: cfe/trunk/test/SemaTemplate/friend-template.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend-template.cpp?rev=300443=300442=300443=diff
==
--- cfe/trunk/test/SemaTemplate/friend-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/friend-template.cpp Mon Apr 17 03:51:20 2017
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
  // PR5057
  namespace test0 {
namespace std {
@@ -68,17 +68,12 @@ namespace test3 {
Foo foo;

template struct X2a;
-
-  template struct X2b;
+  template struct X2b;// expected-note {{previous 
non-type template parameter with type 'int' is here}}

template
class X3 {
  template friend struct X2a;
-
-// FIXME: the redeclaration note ends up here because redeclaration
-// lookup ends up finding the friend target from X3.
-template friend struct X2b; // 

[PATCH] D32138: clang-cl: Support the /Zc:twoPhase[-] command-line option (PR32680)

2017-04-17 Thread Hans Wennborg via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL300501: clang-cl: Support the /Zc:twoPhase[-] command-line 
option (PR32680) (authored by hans).

Changed prior to commit:
  https://reviews.llvm.org/D32138?vs=95489=95494#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D32138

Files:
  cfe/trunk/include/clang/Driver/CLCompatOptions.td
  cfe/trunk/test/Driver/cl-options.c


Index: cfe/trunk/include/clang/Driver/CLCompatOptions.td
===
--- cfe/trunk/include/clang/Driver/CLCompatOptions.td
+++ cfe/trunk/include/clang/Driver/CLCompatOptions.td
@@ -172,6 +172,12 @@
   HelpText<"Enable trigraphs">, Alias;
 def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">,
   HelpText<"Disable trigraphs (default)">, Alias;
+def _SLASH_Zc_twoPhase : CLFlag<"Zc:twoPhase">,
+  HelpText<"Enable two-phase name lookup in templates">,
+  Alias;
+def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">,
+  HelpText<"Disable two-phase name lookup in templates">,
+  Alias;
 def _SLASH_Z7 : CLFlag<"Z7">,
   HelpText<"Enable CodeView debug information in object files">;
 def _SLASH_Zd : CLFlag<"Zd">,
Index: cfe/trunk/test/Driver/cl-options.c
===
--- cfe/trunk/test/Driver/cl-options.c
+++ cfe/trunk/test/Driver/cl-options.c
@@ -296,11 +296,14 @@
 // NOSTRICT: "-relaxed-aliasing"
 
 // We recognize -f[no-]delayed-template-parsing.
+// /Zc:twoPhase[-] has the opposite meaning.
 // RUN: %clang_cl -c -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDDEFAULT 
%s
 // DELAYEDDEFAULT: "-fdelayed-template-parsing"
 // RUN: %clang_cl -c -fdelayed-template-parsing -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDON %s
+// RUN: %clang_cl -c /Zc:twoPhase- -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDON %s
 // DELAYEDON: "-fdelayed-template-parsing"
 // RUN: %clang_cl -c -fno-delayed-template-parsing -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDOFF %s
+// RUN: %clang_cl -c /Zc:twoPhase -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDOFF %s
 // DELAYEDOFF-NOT: "-fdelayed-template-parsing"
 
 // For some warning ids, we can map from MSVC warning to Clang warning.


Index: cfe/trunk/include/clang/Driver/CLCompatOptions.td
===
--- cfe/trunk/include/clang/Driver/CLCompatOptions.td
+++ cfe/trunk/include/clang/Driver/CLCompatOptions.td
@@ -172,6 +172,12 @@
   HelpText<"Enable trigraphs">, Alias;
 def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">,
   HelpText<"Disable trigraphs (default)">, Alias;
+def _SLASH_Zc_twoPhase : CLFlag<"Zc:twoPhase">,
+  HelpText<"Enable two-phase name lookup in templates">,
+  Alias;
+def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">,
+  HelpText<"Disable two-phase name lookup in templates">,
+  Alias;
 def _SLASH_Z7 : CLFlag<"Z7">,
   HelpText<"Enable CodeView debug information in object files">;
 def _SLASH_Zd : CLFlag<"Zd">,
Index: cfe/trunk/test/Driver/cl-options.c
===
--- cfe/trunk/test/Driver/cl-options.c
+++ cfe/trunk/test/Driver/cl-options.c
@@ -296,11 +296,14 @@
 // NOSTRICT: "-relaxed-aliasing"
 
 // We recognize -f[no-]delayed-template-parsing.
+// /Zc:twoPhase[-] has the opposite meaning.
 // RUN: %clang_cl -c -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDDEFAULT %s
 // DELAYEDDEFAULT: "-fdelayed-template-parsing"
 // RUN: %clang_cl -c -fdelayed-template-parsing -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDON %s
+// RUN: %clang_cl -c /Zc:twoPhase- -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDON %s
 // DELAYEDON: "-fdelayed-template-parsing"
 // RUN: %clang_cl -c -fno-delayed-template-parsing -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDOFF %s
+// RUN: %clang_cl -c /Zc:twoPhase -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDOFF %s
 // DELAYEDOFF-NOT: "-fdelayed-template-parsing"
 
 // For some warning ids, we can map from MSVC warning to Clang warning.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r300501 - clang-cl: Support the /Zc:twoPhase[-] command-line option (PR32680)

2017-04-17 Thread Hans Wennborg via cfe-commits
Author: hans
Date: Mon Apr 17 16:28:36 2017
New Revision: 300501

URL: http://llvm.org/viewvc/llvm-project?rev=300501=rev
Log:
clang-cl: Support the /Zc:twoPhase[-] command-line option (PR32680)

It sounds like MSVC is adding support for two-phase name lookup in a
future version, enabled by this flag (see bug).

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

Modified:
cfe/trunk/include/clang/Driver/CLCompatOptions.td
cfe/trunk/test/Driver/cl-options.c

Modified: cfe/trunk/include/clang/Driver/CLCompatOptions.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CLCompatOptions.td?rev=300501=300500=300501=diff
==
--- cfe/trunk/include/clang/Driver/CLCompatOptions.td (original)
+++ cfe/trunk/include/clang/Driver/CLCompatOptions.td Mon Apr 17 16:28:36 2017
@@ -172,6 +172,12 @@ def _SLASH_Zc_trigraphs : CLFlag<"Zc:tri
   HelpText<"Enable trigraphs">, Alias;
 def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">,
   HelpText<"Disable trigraphs (default)">, Alias;
+def _SLASH_Zc_twoPhase : CLFlag<"Zc:twoPhase">,
+  HelpText<"Enable two-phase name lookup in templates">,
+  Alias;
+def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">,
+  HelpText<"Disable two-phase name lookup in templates">,
+  Alias;
 def _SLASH_Z7 : CLFlag<"Z7">,
   HelpText<"Enable CodeView debug information in object files">;
 def _SLASH_Zd : CLFlag<"Zd">,

Modified: cfe/trunk/test/Driver/cl-options.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/cl-options.c?rev=300501=300500=300501=diff
==
--- cfe/trunk/test/Driver/cl-options.c (original)
+++ cfe/trunk/test/Driver/cl-options.c Mon Apr 17 16:28:36 2017
@@ -296,11 +296,14 @@
 // NOSTRICT: "-relaxed-aliasing"
 
 // We recognize -f[no-]delayed-template-parsing.
+// /Zc:twoPhase[-] has the opposite meaning.
 // RUN: %clang_cl -c -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDDEFAULT 
%s
 // DELAYEDDEFAULT: "-fdelayed-template-parsing"
 // RUN: %clang_cl -c -fdelayed-template-parsing -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDON %s
+// RUN: %clang_cl -c /Zc:twoPhase- -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDON %s
 // DELAYEDON: "-fdelayed-template-parsing"
 // RUN: %clang_cl -c -fno-delayed-template-parsing -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDOFF %s
+// RUN: %clang_cl -c /Zc:twoPhase -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDOFF %s
 // DELAYEDOFF-NOT: "-fdelayed-template-parsing"
 
 // For some warning ids, we can map from MSVC warning to Clang warning.


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


Re: r300443 - Address http://bugs.llvm.org/pr30994 so that a non-friend can properly replace a friend, and a visible friend can properly replace an invisible friend but not vice verse, and definitions

2017-04-17 Thread Yaron Keren via cfe-commits
Thanks, I will look into this.


ā€«×‘×Ŗא×Øיך יום ג׳, 18 באפ×Ø׳ 2017 ב-0:11 מא×Ŗ ā€ŖBenjamin Kramerā€¬ā€ <ā€Ŗ
benny@gmail.comā€¬ā€>:ā€¬

> This broke our internal build of libc++ with modules. Reduced test
> case attached, courtesy of Richard Smith!
>
> With your patch it doesn't compiler anymore:
> While building module 'x':
> In file included from :2:
> In file included from ./c.h:1:
> ./a.h:3:32: error: inline declaration of 'f' follows non-inline definition
> template inline void f() {}
>^
> ./a.h:3:32: note: previous definition is here
> template inline void f() {}
>
>
> I reverted this change in r300497.
>
> On Mon, Apr 17, 2017 at 10:51 AM, Yaron Keren via cfe-commits
>  wrote:
> > Author: yrnkrn
> > Date: Mon Apr 17 03:51:20 2017
> > New Revision: 300443
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=300443=rev
> > Log:
> > Address http://bugs.llvm.org/pr30994 so that a non-friend can properly
> replace a friend, and a visible friend can properly replace an invisible
> friend but not vice verse, and definitions are not replaced. This fixes the
> two FIXME in SemaTemplate/friend-template.cpp.
> >
> > The code implements Richard Smith suggestion in comment 3 of the PR.
> >
> > reviewer: Vassil Vassilev
> >
> > Differential Revision: https://reviews.llvm.org/D31540
> >
> >
> > Modified:
> > cfe/trunk/include/clang/AST/DeclBase.h
> > cfe/trunk/lib/AST/Decl.cpp
> > cfe/trunk/lib/AST/DeclBase.cpp
> > cfe/trunk/test/SemaTemplate/friend-template.cpp
> >
> > Modified: cfe/trunk/include/clang/AST/DeclBase.h
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=300443=300442=300443=diff
> >
> ==
> > --- cfe/trunk/include/clang/AST/DeclBase.h (original)
> > +++ cfe/trunk/include/clang/AST/DeclBase.h Mon Apr 17 03:51:20 2017
> > @@ -417,6 +417,8 @@ public:
> >  return const_cast(this)->getTranslationUnitDecl();
> >}
> >
> > +  bool isThisDeclarationADefinition() const;
> > +
> >bool isInAnonymousNamespace() const;
> >
> >bool isInStdNamespace() const;
> >
> > Modified: cfe/trunk/lib/AST/Decl.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=300443=300442=300443=diff
> >
> ==
> > --- cfe/trunk/lib/AST/Decl.cpp (original)
> > +++ cfe/trunk/lib/AST/Decl.cpp Mon Apr 17 03:51:20 2017
> > @@ -1536,6 +1536,10 @@ bool NamedDecl::declarationReplaces(Name
> >if (isa(this))
> >  return false;
> >
> > +  if (getFriendObjectKind() > OldD->getFriendObjectKind() &&
> > +  !isThisDeclarationADefinition())
> > +return false;
> > +
> >// For parameters, pick the newer one. This is either an error or (in
> >// Objective-C) permitted as an extension.
> >if (isa(this))
> >
> > Modified: cfe/trunk/lib/AST/DeclBase.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=300443=300442=300443=diff
> >
> ==
> > --- cfe/trunk/lib/AST/DeclBase.cpp (original)
> > +++ cfe/trunk/lib/AST/DeclBase.cpp Mon Apr 17 03:51:20 2017
> > @@ -861,6 +861,21 @@ const FunctionType *Decl::getFunctionTyp
> >return Ty->getAs();
> >  }
> >
> > +bool Decl::isThisDeclarationADefinition() const {
> > +  if (auto *TD = dyn_cast(this))
> > +return TD->isThisDeclarationADefinition();
> > +  if (auto *FD = dyn_cast(this))
> > +return FD->isThisDeclarationADefinition();
> > +  if (auto *VD = dyn_cast(this))
> > +return VD->isThisDeclarationADefinition();
> > +  if (auto *CTD = dyn_cast(this))
> > +return CTD->isThisDeclarationADefinition();
> > +  if (auto *FTD = dyn_cast(this))
> > +return FTD->isThisDeclarationADefinition();
> > +  if (auto *VTD = dyn_cast(this))
> > +return VTD->isThisDeclarationADefinition();
> > +  return false;
> > +}
> >
> >  /// Starting at a given context (a Decl or DeclContext), look for a
> >  /// code context that is not a closure (a lambda, block, etc.).
> >
> > Modified: cfe/trunk/test/SemaTemplate/friend-template.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend-template.cpp?rev=300443=300442=300443=diff
> >
> ==
> > --- cfe/trunk/test/SemaTemplate/friend-template.cpp (original)
> > +++ cfe/trunk/test/SemaTemplate/friend-template.cpp Mon Apr 17 03:51:20
> 2017
> > @@ -1,4 +1,4 @@
> > -// RUN: %clang_cc1 -fsyntax-only -verify %s
> > +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
> >  // PR5057
> >  namespace test0 {
> >namespace std {
> > @@ -68,17 +68,12 @@ namespace test3 {
> >Foo foo;
> >
> >template struct X2a;
> > -
> > -  template struct X2b;
> > +  template struct X2b;// expected-note
> {{previous non-type template parameter with 

[PATCH] D32138: clang-cl: Support the /Zc:twoPhase[-] command-line option (PR32680)

2017-04-17 Thread Reid Kleckner via Phabricator via cfe-commits
rnk accepted this revision.
rnk added a comment.
This revision is now accepted and ready to land.

Let's add it now. If we don't add this, some user will run into it first and 
have to wait for a fix. If we add it and get the meaning wrong, we'll still 
need to fix it and push a new release, so we're no worse off.

lgtm


https://reviews.llvm.org/D32138



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


[PATCH] D32064: [asan] Disable ASan global-GC depending on the target and compiler flags

2017-04-17 Thread Reid Kleckner via Phabricator via cfe-commits
rnk added a comment.

In https://reviews.llvm.org/D32064#726861, @pcc wrote:

> I think it would be better to move this logic to the driver and have it pass 
> in an `-mllvm` flag. The sanitizer passes should really be taking no 
> arguments in the constructor like the other passes, so I don't want us to add 
> another argument here.


That seems like the opposite of the direction we've been moving, though. 
cl::opt flags can't appear twice, and this means one process can't do two asan 
compilations in two LLVMContexts in parallel with different settings.




Comment at: lib/Driver/SanitizerArgs.cpp:636
+  case llvm::Triple::COFF:
+return DataSections;
+  case llvm::Triple::ELF:

We can return true for COFF here. By adding a comdat during asan 
instrumentation, we effectively implement -fdata-sections ourselves. If the 
user really wanted -fno-data-sections for some reason, they're out of luck 
right now.


Repository:
  rL LLVM

https://reviews.llvm.org/D32064



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


[PATCH] D32138: clang-cl: Support the /Zc:twoPhase[-] command-line option (PR32680)

2017-04-17 Thread Hans Wennborg via Phabricator via cfe-commits
hans added a comment.

We could wait until a version of MSVC ships with this, in case they decide to 
change the name, or we could just land it now.


https://reviews.llvm.org/D32138



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


[PATCH] D32138: clang-cl: Support the /Zc:twoPhase[-] command-line option (PR32680)

2017-04-17 Thread Hans Wennborg via Phabricator via cfe-commits
hans created this revision.

It sounds like MSVC is adding support for two-phase name lookup in a future 
version, enabled by this flag (see bug).


https://reviews.llvm.org/D32138

Files:
  include/clang/Driver/CLCompatOptions.td
  test/Driver/cl-options.c


Index: test/Driver/cl-options.c
===
--- test/Driver/cl-options.c
+++ test/Driver/cl-options.c
@@ -296,11 +296,14 @@
 // NOSTRICT: "-relaxed-aliasing"
 
 // We recognize -f[no-]delayed-template-parsing.
+// /Zc:twoPhase[-] has the opposite meaning.
 // RUN: %clang_cl -c -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDDEFAULT 
%s
 // DELAYEDDEFAULT: "-fdelayed-template-parsing"
 // RUN: %clang_cl -c -fdelayed-template-parsing -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDON %s
+// RUN: %clang_cl -c /Zc:twoPhase- -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDON %s
 // DELAYEDON: "-fdelayed-template-parsing"
 // RUN: %clang_cl -c -fno-delayed-template-parsing -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDOFF %s
+// RUN: %clang_cl -c /Zc:twoPhase -### -- %s 2>&1 | FileCheck 
-check-prefix=DELAYEDOFF %s
 // DELAYEDOFF-NOT: "-fdelayed-template-parsing"
 
 // For some warning ids, we can map from MSVC warning to Clang warning.
Index: include/clang/Driver/CLCompatOptions.td
===
--- include/clang/Driver/CLCompatOptions.td
+++ include/clang/Driver/CLCompatOptions.td
@@ -172,6 +172,12 @@
   HelpText<"Enable trigraphs">, Alias;
 def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">,
   HelpText<"Disable trigraphs (default)">, Alias;
+def _SLASH_Zc_twoPhase : CLFlag<"Zc:twoPhase">,
+  HelpText<"Enable two-phase name lookup in templates">,
+  Alias;
+def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">,
+  HelpText<"Disable two-phase name lookup in templates">,
+  Alias;
 def _SLASH_Z7 : CLFlag<"Z7">,
   HelpText<"Enable CodeView debug information in object files">;
 def _SLASH_Zd : CLFlag<"Zd">,


Index: test/Driver/cl-options.c
===
--- test/Driver/cl-options.c
+++ test/Driver/cl-options.c
@@ -296,11 +296,14 @@
 // NOSTRICT: "-relaxed-aliasing"
 
 // We recognize -f[no-]delayed-template-parsing.
+// /Zc:twoPhase[-] has the opposite meaning.
 // RUN: %clang_cl -c -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDDEFAULT %s
 // DELAYEDDEFAULT: "-fdelayed-template-parsing"
 // RUN: %clang_cl -c -fdelayed-template-parsing -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDON %s
+// RUN: %clang_cl -c /Zc:twoPhase- -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDON %s
 // DELAYEDON: "-fdelayed-template-parsing"
 // RUN: %clang_cl -c -fno-delayed-template-parsing -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDOFF %s
+// RUN: %clang_cl -c /Zc:twoPhase -### -- %s 2>&1 | FileCheck -check-prefix=DELAYEDOFF %s
 // DELAYEDOFF-NOT: "-fdelayed-template-parsing"
 
 // For some warning ids, we can map from MSVC warning to Clang warning.
Index: include/clang/Driver/CLCompatOptions.td
===
--- include/clang/Driver/CLCompatOptions.td
+++ include/clang/Driver/CLCompatOptions.td
@@ -172,6 +172,12 @@
   HelpText<"Enable trigraphs">, Alias;
 def _SLASH_Zc_trigraphs_off : CLFlag<"Zc:trigraphs-">,
   HelpText<"Disable trigraphs (default)">, Alias;
+def _SLASH_Zc_twoPhase : CLFlag<"Zc:twoPhase">,
+  HelpText<"Enable two-phase name lookup in templates">,
+  Alias;
+def _SLASH_Zc_twoPhase_ : CLFlag<"Zc:twoPhase-">,
+  HelpText<"Disable two-phase name lookup in templates">,
+  Alias;
 def _SLASH_Z7 : CLFlag<"Z7">,
   HelpText<"Enable CodeView debug information in object files">;
 def _SLASH_Zd : CLFlag<"Zd">,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: r300443 - Address http://bugs.llvm.org/pr30994 so that a non-friend can properly replace a friend, and a visible friend can properly replace an invisible friend but not vice verse, and definitions

2017-04-17 Thread Benjamin Kramer via cfe-commits
This broke our internal build of libc++ with modules. Reduced test
case attached, courtesy of Richard Smith!

With your patch it doesn't compiler anymore:
While building module 'x':
In file included from :2:
In file included from ./c.h:1:
./a.h:3:32: error: inline declaration of 'f' follows non-inline definition
template inline void f() {}
   ^
./a.h:3:32: note: previous definition is here
template inline void f() {}


I reverted this change in r300497.

On Mon, Apr 17, 2017 at 10:51 AM, Yaron Keren via cfe-commits
 wrote:
> Author: yrnkrn
> Date: Mon Apr 17 03:51:20 2017
> New Revision: 300443
>
> URL: http://llvm.org/viewvc/llvm-project?rev=300443=rev
> Log:
> Address http://bugs.llvm.org/pr30994 so that a non-friend can properly 
> replace a friend, and a visible friend can properly replace an invisible 
> friend but not vice verse, and definitions are not replaced. This fixes the 
> two FIXME in SemaTemplate/friend-template.cpp.
>
> The code implements Richard Smith suggestion in comment 3 of the PR.
>
> reviewer: Vassil Vassilev
>
> Differential Revision: https://reviews.llvm.org/D31540
>
>
> Modified:
> cfe/trunk/include/clang/AST/DeclBase.h
> cfe/trunk/lib/AST/Decl.cpp
> cfe/trunk/lib/AST/DeclBase.cpp
> cfe/trunk/test/SemaTemplate/friend-template.cpp
>
> Modified: cfe/trunk/include/clang/AST/DeclBase.h
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=300443=300442=300443=diff
> ==
> --- cfe/trunk/include/clang/AST/DeclBase.h (original)
> +++ cfe/trunk/include/clang/AST/DeclBase.h Mon Apr 17 03:51:20 2017
> @@ -417,6 +417,8 @@ public:
>  return const_cast(this)->getTranslationUnitDecl();
>}
>
> +  bool isThisDeclarationADefinition() const;
> +
>bool isInAnonymousNamespace() const;
>
>bool isInStdNamespace() const;
>
> Modified: cfe/trunk/lib/AST/Decl.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=300443=300442=300443=diff
> ==
> --- cfe/trunk/lib/AST/Decl.cpp (original)
> +++ cfe/trunk/lib/AST/Decl.cpp Mon Apr 17 03:51:20 2017
> @@ -1536,6 +1536,10 @@ bool NamedDecl::declarationReplaces(Name
>if (isa(this))
>  return false;
>
> +  if (getFriendObjectKind() > OldD->getFriendObjectKind() &&
> +  !isThisDeclarationADefinition())
> +return false;
> +
>// For parameters, pick the newer one. This is either an error or (in
>// Objective-C) permitted as an extension.
>if (isa(this))
>
> Modified: cfe/trunk/lib/AST/DeclBase.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=300443=300442=300443=diff
> ==
> --- cfe/trunk/lib/AST/DeclBase.cpp (original)
> +++ cfe/trunk/lib/AST/DeclBase.cpp Mon Apr 17 03:51:20 2017
> @@ -861,6 +861,21 @@ const FunctionType *Decl::getFunctionTyp
>return Ty->getAs();
>  }
>
> +bool Decl::isThisDeclarationADefinition() const {
> +  if (auto *TD = dyn_cast(this))
> +return TD->isThisDeclarationADefinition();
> +  if (auto *FD = dyn_cast(this))
> +return FD->isThisDeclarationADefinition();
> +  if (auto *VD = dyn_cast(this))
> +return VD->isThisDeclarationADefinition();
> +  if (auto *CTD = dyn_cast(this))
> +return CTD->isThisDeclarationADefinition();
> +  if (auto *FTD = dyn_cast(this))
> +return FTD->isThisDeclarationADefinition();
> +  if (auto *VTD = dyn_cast(this))
> +return VTD->isThisDeclarationADefinition();
> +  return false;
> +}
>
>  /// Starting at a given context (a Decl or DeclContext), look for a
>  /// code context that is not a closure (a lambda, block, etc.).
>
> Modified: cfe/trunk/test/SemaTemplate/friend-template.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend-template.cpp?rev=300443=300442=300443=diff
> ==
> --- cfe/trunk/test/SemaTemplate/friend-template.cpp (original)
> +++ cfe/trunk/test/SemaTemplate/friend-template.cpp Mon Apr 17 03:51:20 2017
> @@ -1,4 +1,4 @@
> -// RUN: %clang_cc1 -fsyntax-only -verify %s
> +// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
>  // PR5057
>  namespace test0 {
>namespace std {
> @@ -68,17 +68,12 @@ namespace test3 {
>Foo foo;
>
>template struct X2a;
> -
> -  template struct X2b;
> +  template struct X2b;// expected-note {{previous 
> non-type template parameter with type 'int' is here}}
>
>template
>class X3 {
>  template friend struct X2a;
> -
> -// FIXME: the redeclaration note ends up here because redeclaration
> -// lookup ends up finding the friend target from X3.
> -template friend struct X2b; // expected-error 
> {{template non-type parameter has a different type 'long' in template 
> 

r300497 - Revert "Address http://bugs.llvm.org/pr30994 so that a non-friend can properly replace a friend, and a visible friend can properly replace an invisible friend but not vice verse, and definit

2017-04-17 Thread Benjamin Kramer via cfe-commits
Author: d0k
Date: Mon Apr 17 15:57:40 2017
New Revision: 300497

URL: http://llvm.org/viewvc/llvm-project?rev=300497=rev
Log:
Revert "Address http://bugs.llvm.org/pr30994 so that a non-friend can properly 
replace a friend, and a visible friend can properly replace an invisible friend 
but not vice verse, and definitions are not replaced. This fixes the two FIXME 
in SemaTemplate/friend-template.cpp."

This reverts commit r300443. Breaks compiling libc++ with modules in
some configurations.

Modified:
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/test/SemaTemplate/friend-template.cpp

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=300497=300496=300497=diff
==
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Mon Apr 17 15:57:40 2017
@@ -417,8 +417,6 @@ public:
 return const_cast(this)->getTranslationUnitDecl();
   }
 
-  bool isThisDeclarationADefinition() const;
-
   bool isInAnonymousNamespace() const;
 
   bool isInStdNamespace() const;

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=300497=300496=300497=diff
==
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon Apr 17 15:57:40 2017
@@ -1536,10 +1536,6 @@ bool NamedDecl::declarationReplaces(Name
   if (isa(this))
 return false;
 
-  if (getFriendObjectKind() > OldD->getFriendObjectKind() &&
-  !isThisDeclarationADefinition())
-return false;
-
   // For parameters, pick the newer one. This is either an error or (in
   // Objective-C) permitted as an extension.
   if (isa(this))

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=300497=300496=300497=diff
==
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Mon Apr 17 15:57:40 2017
@@ -861,21 +861,6 @@ const FunctionType *Decl::getFunctionTyp
   return Ty->getAs();
 }
 
-bool Decl::isThisDeclarationADefinition() const {
-  if (auto *TD = dyn_cast(this))
-return TD->isThisDeclarationADefinition();
-  if (auto *FD = dyn_cast(this))
-return FD->isThisDeclarationADefinition();
-  if (auto *VD = dyn_cast(this))
-return VD->isThisDeclarationADefinition();
-  if (auto *CTD = dyn_cast(this))
-return CTD->isThisDeclarationADefinition();
-  if (auto *FTD = dyn_cast(this))
-return FTD->isThisDeclarationADefinition();
-  if (auto *VTD = dyn_cast(this))
-return VTD->isThisDeclarationADefinition();
-  return false;
-}
 
 /// Starting at a given context (a Decl or DeclContext), look for a
 /// code context that is not a closure (a lambda, block, etc.).

Modified: cfe/trunk/test/SemaTemplate/friend-template.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend-template.cpp?rev=300497=300496=300497=diff
==
--- cfe/trunk/test/SemaTemplate/friend-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/friend-template.cpp Mon Apr 17 15:57:40 2017
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s
 // PR5057
 namespace test0 {
   namespace std {
@@ -68,12 +68,17 @@ namespace test3 {
   Foo foo;
 
   template struct X2a;
-  template struct X2b;// expected-note {{previous 
non-type template parameter with type 'int' is here}}
+
+  template struct X2b;
 
   template
   class X3 {
 template friend struct X2a;
-template friend struct X2b; // expected-error 
{{template non-type parameter has a different type 'long' in template 
redeclaration}} 
+
+// FIXME: the redeclaration note ends up here because redeclaration
+// lookup ends up finding the friend target from X3.
+template friend struct X2b; // expected-error 
{{template non-type parameter has a different type 'long' in template 
redeclaration}} \
+  // expected-note {{previous non-type template parameter with type 'int' 
is here}}
   };
 
   X3 x3i; // okay
@@ -292,11 +297,14 @@ namespace PR12585 {
   int n = C::D().f();
 
   struct F {
-template struct G; // expected-note {{previous}}
+template struct G;
   };
   template struct H {
+// FIXME: As with cases above, the note here is on an unhelpful 
declaration,
+// and should point to the declaration of G within F.
 template friend struct F::G; // \
-  // expected-error {{different type 'char' in template redeclaration}}
+  // expected-error {{different type 'char' in template redeclaration}} \
+  // expected-note {{previous}}
   };
  

[PATCH] D31830: Emit invariant.group.barrier when using union field

2017-04-17 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek added inline comments.



Comment at: lib/CodeGen/CGExpr.cpp:3517
+CGM.getCodeGenOpts().StrictVTablePointers &&
+CGM.getCodeGenOpts().OptimizationLevel > 0)
+  addr = Address(Builder.CreateInvariantGroupBarrier(addr.getPointer()),

rjmccall wrote:
> Prazek wrote:
> > rjmccall wrote:
> > > Checking for v-table pointers recursively isn't really that difficult, 
> > > but if you really don't want to do that, please at least check for 
> > > non-POD-ness or something so that this isn't kicking in for literally 
> > > every struct type.
> > ok, I am also planning to fix this in the later patch, because the same 
> > problem arise when comparing 2 pointers to dynamic classe. 
> > I would like to have a bit in CXXRecordDecl to remember if it has any vptr 
> > inside that would calculate durring the construction. 
> > My biggest fear is that if I won't cache it then it will be very slow.
> We could repeat this work from scratch on every single union field access 
> done by IRGen and it would still be way, way faster than doing anything extra 
> on every record definition in the program.  The latter is done orders of 
> magnitude more frequently than the former.
This is a good point, and actually I don't need to check if class holds any 
vptrs for the example I refered (comparing 2 pointers).
Hovewer I still need to do it when someone casts pointer to class holding vptrs 
to something that doesn't hold vptrs, and any pointer casts are much more 
frequent than Record declarations.


https://reviews.llvm.org/D31830



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


[PATCH] D31487: [coroutines] Fix rebuilding of implicit and dependent coroutine statements.

2017-04-17 Thread Eric Fiselier via Phabricator via cfe-commits
EricWF reopened this revision.
EricWF added a comment.
This revision is now accepted and ready to land.

I have to revert this commit due to test failures. I think I uploaded an 
incorrect patch or bad merge because the tests passed on my machine.


https://reviews.llvm.org/D31487



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


[PATCH] D32110: Emit invariant.group loads with empty group md

2017-04-17 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added a comment.
This revision is now accepted and ready to land.

Okay.


Repository:
  rL LLVM

https://reviews.llvm.org/D32110



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


[libcxx] r300489 - Fix passing incorrectly value-category when constructing unique_ptr's deleter

2017-04-17 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Mon Apr 17 15:20:27 2017
New Revision: 300489

URL: http://llvm.org/viewvc/llvm-project?rev=300489=rev
Log:
Fix passing incorrectly value-category when constructing unique_ptr's deleter

Modified:
libcxx/trunk/include/memory

libcxx/trunk/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp

Modified: libcxx/trunk/include/memory
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=300489=300488=300489=diff
==
--- libcxx/trunk/include/memory (original)
+++ libcxx/trunk/include/memory Mon Apr 17 15:20:27 2017
@@ -2734,7 +2734,7 @@ public:
   >
   _LIBCPP_INLINE_VISIBILITY
   unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
-  : __ptr_(__u.release(), _VSTD::forward(__u.get_deleter())) 
{
+  : __ptr_(__u.release(), _VSTD::forward<_Ep>(__u.get_deleter())) {
   }
 
   template http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp?rev=300489=300488=300489=diff
==
--- 
libcxx/trunk/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/move_convert.pass.cpp
 Mon Apr 17 15:20:27 2017
@@ -19,6 +19,7 @@
 #include 
 
 #include "test_macros.h"
+#include "type_id.h"
 #include "unique_ptr_test_helper.h"
 
 template 
@@ -33,9 +34,71 @@ struct GenericConvertingDeleter {
   void operator()(void*) const {}
 };
 
+template 
+struct is_specialization;
+
+template  class Templ, int ID1, class Other>
+struct is_specialization : std::false_type {};
+
+template  class Templ, int ID1, int ID2>
+struct is_specialization : std::true_type {};
+
+template 
+using EnableIfSpecialization = typename std::enable_if<
+is_specialization::value
+  >::type;
+
+
+template 
+struct TrackingDeleter {
+  TrackingDeleter() : arg_type(<>()) {}
+
+  TrackingDeleter(TrackingDeleter const&)
+  : arg_type(()) {}
+
+  TrackingDeleter(TrackingDeleter&&)
+  : arg_type(()) {}
+
+  template  >
+  TrackingDeleter(T&&) : arg_type(()) {}
+
+  TrackingDeleter& operator=(TrackingDeleter const&) {
+arg_type = ();
+return *this;
+  }
+
+  TrackingDeleter& operator=(TrackingDeleter &&) {
+arg_type = ();
+return *this;
+  }
+
+  template  >
+  TrackingDeleter& operator=(T&&) {
+arg_type = ();
+return *this;
+  }
+
+  void operator()(void*) const {}
+
+public:
+  TypeID const* reset() const {
+TypeID const* tmp = arg_type;
+arg_type = nullptr;
+return tmp;
+  }
+
+  mutable TypeID const* arg_type;
+};
+
+
+template 
+bool checkArg(TrackingDeleter const& d) {
+  return d.arg_type && *d.arg_type == makeArgumentID();
+}
+
+
 template 
 void test_sfinae() {
-#if TEST_STD_VER >= 11
   typedef typename std::conditional::type VT;
 
   { // Test that different non-reference deleter types are allowed so long
@@ -80,13 +143,11 @@ void test_sfinae() {
 static_assert(std::is_constructible::value, "");
 static_assert(std::is_constructible::value, "");
   }
-#endif
 }
 
 
 template 
 void test_noexcept() {
-#if TEST_STD_VER >= 11
   typedef typename std::conditional::type VT;
   {
 typedef std::unique_ptr APtr;
@@ -108,7 +169,39 @@ void test_noexcept() {
 typedef std::unique_ptr BPtr;
 static_assert(std::is_nothrow_constructible::value, "");
   }
-#endif
+}
+
+
+template 
+void test_deleter_value_category() {
+  typedef typename std::conditional::type VT;
+  using TD1 = TrackingDeleter<1>;
+  using TD2 = TrackingDeleter<2>;
+  TD1 d1;
+  TD2 d2;
+
+  { // Test non-reference deleter conversions
+using U1 = std::unique_ptr;
+using U2 = std::unique_ptr;
+U2 u2;
+u2.get_deleter().reset();
+U1 u1(std::move(u2));
+assert(checkArg(u1.get_deleter()));
+  }
+  { // Test assignment from non-const ref
+using U1 = std::unique_ptr;
+using U2 = std::unique_ptr;
+U2 u2(nullptr, d2);
+U1 u1(std::move(u2));
+assert(checkArg(u1.get_deleter()));
+  }
+  { // Test assignment from const ref
+using U1 = std::unique_ptr;
+using U2 = std::unique_ptr;
+U2 u2(nullptr, d2);
+U1 u1(std::move(u2));
+assert(checkArg(u1.get_deleter()));
+  }
 }
 
 
@@ -116,9 +209,11 @@ int main() {
   {
 test_sfinae();
 test_noexcept();
+test_deleter_value_category();
   }
   {
 test_sfinae();
 test_noexcept();
+test_deleter_value_category();
   }
 }


___
cfe-commits mailing list

[libcxx] r300488 - [optional] Update synopsis for LWG2934

2017-04-17 Thread Casey Carter via cfe-commits
Author: caseycarter
Date: Mon Apr 17 15:15:16 2017
New Revision: 300488

URL: http://llvm.org/viewvc/llvm-project?rev=300488=rev
Log:
[optional] Update synopsis for LWG2934

(comment-only change)

Modified:
libcxx/trunk/include/optional
libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/equal.pass.cpp

libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/greater.pass.cpp

libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/greater_equal.pass.cpp

libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/less_equal.pass.cpp

libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/less_than.pass.cpp

libcxx/trunk/test/std/utilities/optional/optional.comp_with_t/not_equal.pass.cpp
libcxx/trunk/test/std/utilities/optional/optional.relops/equal.pass.cpp

libcxx/trunk/test/std/utilities/optional/optional.relops/greater_equal.pass.cpp

libcxx/trunk/test/std/utilities/optional/optional.relops/greater_than.pass.cpp
libcxx/trunk/test/std/utilities/optional/optional.relops/less_equal.pass.cpp
libcxx/trunk/test/std/utilities/optional/optional.relops/less_than.pass.cpp
libcxx/trunk/test/std/utilities/optional/optional.relops/not_equal.pass.cpp

Modified: libcxx/trunk/include/optional
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/optional?rev=300488=300487=300488=diff
==
--- libcxx/trunk/include/optional (original)
+++ libcxx/trunk/include/optional Mon Apr 17 15:15:16 2017
@@ -17,29 +17,31 @@
 // C++1z
 
 namespace std {
-  // 20.6.3, optional for object types
+  // 23.6.3, optional for object types
   template  class optional;
 
-  // 20.6.4, no-value state indicator
+  // 23.6.4, no-value state indicator
   struct nullopt_t{see below };
   constexpr nullopt_t nullopt(unspecified );
 
-  // 20.6.5, class bad_optional_access
+  // 23.6.5, class bad_optional_access
   class bad_optional_access;
 
-  // 20.6.6, relational operators
-  template 
-  constexpr bool operator==(const optional&, const optional&);
-  template 
-  constexpr bool operator!=(const optional&, const optional&);
-  template 
-  constexpr bool operator<(const optional&, const optional&);
-  template 
-  constexpr bool operator>(const optional&, const optional&);
-  template 
-  constexpr bool operator<=(const optional&, const optional&);
-  template 
-  constexpr bool operator>=(const optional&, const optional&);
+  // 23.6.6, relational operators
+  template 
+  constexpr bool operator==(const optional&, const optional&);
+  template 
+  constexpr bool operator!=(const optional&, const optional&);
+  template 
+  constexpr bool operator<(const optional&, const optional&);
+  template 
+  constexpr bool operator>(const optional&, const optional&);
+  template 
+  constexpr bool operator<=(const optional&, const optional&);
+  template 
+  constexpr bool operator>=(const optional&, const optional&);
+
+  // 23.6.7 comparison with nullopt
   template  constexpr bool operator==(const optional&, nullopt_t) 
noexcept;
   template  constexpr bool operator==(nullopt_t, const optional&) 
noexcept;
   template  constexpr bool operator!=(const optional&, nullopt_t) 
noexcept;
@@ -53,21 +55,21 @@ namespace std {
   template  constexpr bool operator>=(const optional&, nullopt_t) 
noexcept;
   template  constexpr bool operator>=(nullopt_t, const optional&) 
noexcept;
 
-  // 20.6.8, comparison with T
-  template  constexpr bool operator==(const optional&, const T&);
-  template  constexpr bool operator==(const T&, const optional&);
-  template  constexpr bool operator!=(const optional&, const T&);
-  template  constexpr bool operator!=(const T&, const optional&);
-  template  constexpr bool operator<(const optional&, const T&);
-  template  constexpr bool operator<(const T&, const optional&);
-  template  constexpr bool operator<=(const optional&, const T&);
-  template  constexpr bool operator<=(const T&, const optional&);
-  template  constexpr bool operator>(const optional&, const T&);
-  template  constexpr bool operator>(const T&, const optional&);
-  template  constexpr bool operator>=(const optional&, const T&);
-  template  constexpr bool operator>=(const T&, const optional&);
+  // 23.6.8, comparison with T
+  template  constexpr bool operator==(const optional&, 
const U&);
+  template  constexpr bool operator==(const U&, const 
optional&);
+  template  constexpr bool operator!=(const optional&, 
const U&);
+  template  constexpr bool operator!=(const U&, const 
optional&);
+  template  constexpr bool operator<(const optional&, 
const U&);
+  template  constexpr bool operator<(const U&, const 
optional&);
+  template  constexpr bool operator<=(const optional&, 
const U&);
+  template  constexpr bool operator<=(const U&, const 
optional&);
+  template  constexpr bool operator>(const optional&, 
const U&);
+  template  constexpr bool operator>(const U&, const 
optional&);
+  

[PATCH] D32133: CodeGen: Let byval parameter use alloca address space

2017-04-17 Thread Yaxun Liu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL300487: CodeGen: Let byval parameter use alloca address 
space (authored by yaxunl).

Changed prior to commit:
  https://reviews.llvm.org/D32133?vs=95473=95478#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D32133

Files:
  cfe/trunk/lib/CodeGen/CGCall.cpp
  cfe/trunk/test/CodeGenOpenCL/byval.cl


Index: cfe/trunk/test/CodeGenOpenCL/byval.cl
===
--- cfe/trunk/test/CodeGenOpenCL/byval.cl
+++ cfe/trunk/test/CodeGenOpenCL/byval.cl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---amdgizcl %s | FileCheck %s 
-check-prefix=AMDGIZ
+
+struct A {
+  int x[100];
+};
+
+int f(struct A a);
+
+int g() {
+  struct A a;
+  // CHECK: call i32 @f(%struct.A* byval{{.*}}%a)
+  // AMDGIZ: call i32 @f(%struct.A addrspace(5)* byval{{.*}}%a)
+  return f(a);
+}
+
+// CHECK: declare i32 @f(%struct.A* byval{{.*}})
+// AMDGIZ: declare i32 @f(%struct.A addrspace(5)* byval{{.*}})
Index: cfe/trunk/lib/CodeGen/CGCall.cpp
===
--- cfe/trunk/lib/CodeGen/CGCall.cpp
+++ cfe/trunk/lib/CodeGen/CGCall.cpp
@@ -1586,9 +1586,10 @@
 
 case ABIArgInfo::Indirect: {
   assert(NumIRArgs == 1);
-  // indirect arguments are always on the stack, which is addr space #0.
+  // indirect arguments are always on the stack, which is alloca addr 
space.
   llvm::Type *LTy = ConvertTypeForMem(it->type);
-  ArgTypes[FirstIRArg] = LTy->getPointerTo();
+  ArgTypes[FirstIRArg] = LTy->getPointerTo(
+  CGM.getDataLayout().getAllocaAddrSpace());
   break;
 }
 


Index: cfe/trunk/test/CodeGenOpenCL/byval.cl
===
--- cfe/trunk/test/CodeGenOpenCL/byval.cl
+++ cfe/trunk/test/CodeGenOpenCL/byval.cl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---amdgizcl %s | FileCheck %s -check-prefix=AMDGIZ
+
+struct A {
+  int x[100];
+};
+
+int f(struct A a);
+
+int g() {
+  struct A a;
+  // CHECK: call i32 @f(%struct.A* byval{{.*}}%a)
+  // AMDGIZ: call i32 @f(%struct.A addrspace(5)* byval{{.*}}%a)
+  return f(a);
+}
+
+// CHECK: declare i32 @f(%struct.A* byval{{.*}})
+// AMDGIZ: declare i32 @f(%struct.A addrspace(5)* byval{{.*}})
Index: cfe/trunk/lib/CodeGen/CGCall.cpp
===
--- cfe/trunk/lib/CodeGen/CGCall.cpp
+++ cfe/trunk/lib/CodeGen/CGCall.cpp
@@ -1586,9 +1586,10 @@
 
 case ABIArgInfo::Indirect: {
   assert(NumIRArgs == 1);
-  // indirect arguments are always on the stack, which is addr space #0.
+  // indirect arguments are always on the stack, which is alloca addr space.
   llvm::Type *LTy = ConvertTypeForMem(it->type);
-  ArgTypes[FirstIRArg] = LTy->getPointerTo();
+  ArgTypes[FirstIRArg] = LTy->getPointerTo(
+  CGM.getDataLayout().getAllocaAddrSpace());
   break;
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r300487 - CodeGen: Let byval parameter use alloca address space

2017-04-17 Thread Yaxun Liu via cfe-commits
Author: yaxunl
Date: Mon Apr 17 15:10:44 2017
New Revision: 300487

URL: http://llvm.org/viewvc/llvm-project?rev=300487=rev
Log:
CodeGen: Let byval parameter use alloca address space

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

Added:
cfe/trunk/test/CodeGenOpenCL/byval.cl
Modified:
cfe/trunk/lib/CodeGen/CGCall.cpp

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=300487=300486=300487=diff
==
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Mon Apr 17 15:10:44 2017
@@ -1586,9 +1586,10 @@ CodeGenTypes::GetFunctionType(const CGFu
 
 case ABIArgInfo::Indirect: {
   assert(NumIRArgs == 1);
-  // indirect arguments are always on the stack, which is addr space #0.
+  // indirect arguments are always on the stack, which is alloca addr 
space.
   llvm::Type *LTy = ConvertTypeForMem(it->type);
-  ArgTypes[FirstIRArg] = LTy->getPointerTo();
+  ArgTypes[FirstIRArg] = LTy->getPointerTo(
+  CGM.getDataLayout().getAllocaAddrSpace());
   break;
 }
 

Added: cfe/trunk/test/CodeGenOpenCL/byval.cl
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/byval.cl?rev=300487=auto
==
--- cfe/trunk/test/CodeGenOpenCL/byval.cl (added)
+++ cfe/trunk/test/CodeGenOpenCL/byval.cl Mon Apr 17 15:10:44 2017
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---amdgizcl %s | FileCheck %s 
-check-prefix=AMDGIZ
+
+struct A {
+  int x[100];
+};
+
+int f(struct A a);
+
+int g() {
+  struct A a;
+  // CHECK: call i32 @f(%struct.A* byval{{.*}}%a)
+  // AMDGIZ: call i32 @f(%struct.A addrspace(5)* byval{{.*}}%a)
+  return f(a);
+}
+
+// CHECK: declare i32 @f(%struct.A* byval{{.*}})
+// AMDGIZ: declare i32 @f(%struct.A addrspace(5)* byval{{.*}})


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


[PATCH] D31717: CodeGen: Let lifetime intrinsic use alloca address space

2017-04-17 Thread Yaxun Liu via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL300485: CodeGen: Let lifetime intrinsic use alloca address 
space (authored by yaxunl).

Changed prior to commit:
  https://reviews.llvm.org/D31717?vs=94980=95477#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D31717

Files:
  cfe/trunk/lib/CodeGen/CGDecl.cpp
  cfe/trunk/lib/CodeGen/CodeGenModule.cpp
  cfe/trunk/lib/CodeGen/CodeGenTypeCache.h
  cfe/trunk/test/CodeGenOpenCL/lifetime.cl


Index: cfe/trunk/test/CodeGenOpenCL/lifetime.cl
===
--- cfe/trunk/test/CodeGenOpenCL/lifetime.cl
+++ cfe/trunk/test/CodeGenOpenCL/lifetime.cl
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---amdgizcl %s | FileCheck %s 
-check-prefix=AMDGIZ
+
+void use(char *a);
+
+__attribute__((always_inline)) void helper_no_markers() {
+  char a;
+  use();
+}
+
+void lifetime_test() {
+// CHECK: @llvm.lifetime.start.p0i
+// AMDGIZ: @llvm.lifetime.start.p5i
+  helper_no_markers();
+}
Index: cfe/trunk/lib/CodeGen/CGDecl.cpp
===
--- cfe/trunk/lib/CodeGen/CGDecl.cpp
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp
@@ -924,15 +924,15 @@
 return nullptr;
 
   llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
-  Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
+  Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
   llvm::CallInst *C =
   Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr});
   C->setDoesNotThrow();
   return SizeV;
 }
 
 void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
-  Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
+  Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
   llvm::CallInst *C =
   Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr});
   C->setDoesNotThrow();
@@ -1728,16 +1728,16 @@
   if (LifetimeStartFn)
 return LifetimeStartFn;
   LifetimeStartFn = llvm::Intrinsic::getDeclaration((),
-llvm::Intrinsic::lifetime_start, Int8PtrTy);
+llvm::Intrinsic::lifetime_start, AllocaInt8PtrTy);
   return LifetimeStartFn;
 }
 
 /// Lazily declare the @llvm.lifetime.end intrinsic.
 llvm::Constant *CodeGenModule::getLLVMLifetimeEndFn() {
   if (LifetimeEndFn)
 return LifetimeEndFn;
   LifetimeEndFn = llvm::Intrinsic::getDeclaration((),
-llvm::Intrinsic::lifetime_end, Int8PtrTy);
+llvm::Intrinsic::lifetime_end, AllocaInt8PtrTy);
   return LifetimeEndFn;
 }
 
Index: cfe/trunk/lib/CodeGen/CodeGenTypeCache.h
===
--- cfe/trunk/lib/CodeGen/CodeGenTypeCache.h
+++ cfe/trunk/lib/CodeGen/CodeGenTypeCache.h
@@ -60,6 +60,12 @@
 llvm::PointerType *Int8PtrPtrTy;
   };
 
+  /// void* in alloca address space
+  union {
+llvm::PointerType *AllocaVoidPtrTy;
+llvm::PointerType *AllocaInt8PtrTy;
+  };
+
   /// The size and alignment of the builtin C type 'int'.  This comes
   /// up enough in various ABI lowering tasks to be worth pre-computing.
   union {
Index: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
===
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp
@@ -111,6 +111,8 @@
 C.getTargetInfo().getMaxPointerWidth());
   Int8PtrTy = Int8Ty->getPointerTo(0);
   Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
+  AllocaInt8PtrTy = Int8Ty->getPointerTo(
+  M.getDataLayout().getAllocaAddrSpace());
 
   RuntimeCC = getTargetCodeGenInfo().getABIInfo().getRuntimeCC();
   BuiltinCC = getTargetCodeGenInfo().getABIInfo().getBuiltinCC();


Index: cfe/trunk/test/CodeGenOpenCL/lifetime.cl
===
--- cfe/trunk/test/CodeGenOpenCL/lifetime.cl
+++ cfe/trunk/test/CodeGenOpenCL/lifetime.cl
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---amdgizcl %s | FileCheck %s -check-prefix=AMDGIZ
+
+void use(char *a);
+
+__attribute__((always_inline)) void helper_no_markers() {
+  char a;
+  use();
+}
+
+void lifetime_test() {
+// CHECK: @llvm.lifetime.start.p0i
+// AMDGIZ: @llvm.lifetime.start.p5i
+  helper_no_markers();
+}
Index: cfe/trunk/lib/CodeGen/CGDecl.cpp
===
--- cfe/trunk/lib/CodeGen/CGDecl.cpp
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp
@@ -924,15 +924,15 @@
 return nullptr;
 
   llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
-  Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
+  Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
   llvm::CallInst *C =
   Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr});
   C->setDoesNotThrow();
   return SizeV;
 }
 
 void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
-  Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
+  Addr = 

r300485 - CodeGen: Let lifetime intrinsic use alloca address space

2017-04-17 Thread Yaxun Liu via cfe-commits
Author: yaxunl
Date: Mon Apr 17 15:03:11 2017
New Revision: 300485

URL: http://llvm.org/viewvc/llvm-project?rev=300485=rev
Log:
CodeGen: Let lifetime intrinsic use alloca address space

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

Added:
cfe/trunk/test/CodeGenOpenCL/lifetime.cl
Modified:
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenTypeCache.h

Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=300485=300484=300485=diff
==
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon Apr 17 15:03:11 2017
@@ -924,7 +924,7 @@ llvm::Value *CodeGenFunction::EmitLifeti
 return nullptr;
 
   llvm::Value *SizeV = llvm::ConstantInt::get(Int64Ty, Size);
-  Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
+  Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
   llvm::CallInst *C =
   Builder.CreateCall(CGM.getLLVMLifetimeStartFn(), {SizeV, Addr});
   C->setDoesNotThrow();
@@ -932,7 +932,7 @@ llvm::Value *CodeGenFunction::EmitLifeti
 }
 
 void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
-  Addr = Builder.CreateBitCast(Addr, Int8PtrTy);
+  Addr = Builder.CreateBitCast(Addr, AllocaInt8PtrTy);
   llvm::CallInst *C =
   Builder.CreateCall(CGM.getLLVMLifetimeEndFn(), {Size, Addr});
   C->setDoesNotThrow();
@@ -1728,7 +1728,7 @@ llvm::Constant *CodeGenModule::getLLVMLi
   if (LifetimeStartFn)
 return LifetimeStartFn;
   LifetimeStartFn = llvm::Intrinsic::getDeclaration((),
-llvm::Intrinsic::lifetime_start, Int8PtrTy);
+llvm::Intrinsic::lifetime_start, AllocaInt8PtrTy);
   return LifetimeStartFn;
 }
 
@@ -1737,7 +1737,7 @@ llvm::Constant *CodeGenModule::getLLVMLi
   if (LifetimeEndFn)
 return LifetimeEndFn;
   LifetimeEndFn = llvm::Intrinsic::getDeclaration((),
-llvm::Intrinsic::lifetime_end, Int8PtrTy);
+llvm::Intrinsic::lifetime_end, AllocaInt8PtrTy);
   return LifetimeEndFn;
 }
 

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=300485=300484=300485=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Mon Apr 17 15:03:11 2017
@@ -111,6 +111,8 @@ CodeGenModule::CodeGenModule(ASTContext
 C.getTargetInfo().getMaxPointerWidth());
   Int8PtrTy = Int8Ty->getPointerTo(0);
   Int8PtrPtrTy = Int8PtrTy->getPointerTo(0);
+  AllocaInt8PtrTy = Int8Ty->getPointerTo(
+  M.getDataLayout().getAllocaAddrSpace());
 
   RuntimeCC = getTargetCodeGenInfo().getABIInfo().getRuntimeCC();
   BuiltinCC = getTargetCodeGenInfo().getABIInfo().getBuiltinCC();

Modified: cfe/trunk/lib/CodeGen/CodeGenTypeCache.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypeCache.h?rev=300485=300484=300485=diff
==
--- cfe/trunk/lib/CodeGen/CodeGenTypeCache.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypeCache.h Mon Apr 17 15:03:11 2017
@@ -60,6 +60,12 @@ struct CodeGenTypeCache {
 llvm::PointerType *Int8PtrPtrTy;
   };
 
+  /// void* in alloca address space
+  union {
+llvm::PointerType *AllocaVoidPtrTy;
+llvm::PointerType *AllocaInt8PtrTy;
+  };
+
   /// The size and alignment of the builtin C type 'int'.  This comes
   /// up enough in various ABI lowering tasks to be worth pre-computing.
   union {

Added: cfe/trunk/test/CodeGenOpenCL/lifetime.cl
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/lifetime.cl?rev=300485=auto
==
--- cfe/trunk/test/CodeGenOpenCL/lifetime.cl (added)
+++ cfe/trunk/test/CodeGenOpenCL/lifetime.cl Mon Apr 17 15:03:11 2017
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---amdgizcl %s | FileCheck %s 
-check-prefix=AMDGIZ
+
+void use(char *a);
+
+__attribute__((always_inline)) void helper_no_markers() {
+  char a;
+  use();
+}
+
+void lifetime_test() {
+// CHECK: @llvm.lifetime.start.p0i
+// AMDGIZ: @llvm.lifetime.start.p5i
+  helper_no_markers();
+}


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


[PATCH] D32133: CodeGen: Let byval parameter use alloca address space

2017-04-17 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added a comment.
This revision is now accepted and ready to land.

LGTM.


https://reviews.llvm.org/D32133



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


[PATCH] D32133: CodeGen: Let byval parameter use alloca address space

2017-04-17 Thread Yaxun Liu via Phabricator via cfe-commits
yaxunl created this revision.

https://reviews.llvm.org/D32133

Files:
  lib/CodeGen/CGCall.cpp
  test/CodeGenOpenCL/byval.cl


Index: test/CodeGenOpenCL/byval.cl
===
--- /dev/null
+++ test/CodeGenOpenCL/byval.cl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---amdgizcl %s | FileCheck %s 
-check-prefix=AMDGIZ
+
+struct A {
+  int x[100];
+};
+
+int f(struct A a);
+
+int g() {
+  struct A a;
+  // CHECK: call i32 @f(%struct.A* byval{{.*}}%a)
+  // AMDGIZ: call i32 @f(%struct.A addrspace(5)* byval{{.*}}%a)
+  return f(a);
+}
+
+// CHECK: declare i32 @f(%struct.A* byval{{.*}})
+// AMDGIZ: declare i32 @f(%struct.A addrspace(5)* byval{{.*}})
Index: lib/CodeGen/CGCall.cpp
===
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1586,9 +1586,10 @@
 
 case ABIArgInfo::Indirect: {
   assert(NumIRArgs == 1);
-  // indirect arguments are always on the stack, which is addr space #0.
+  // indirect arguments are always on the stack, which is alloca addr 
space.
   llvm::Type *LTy = ConvertTypeForMem(it->type);
-  ArgTypes[FirstIRArg] = LTy->getPointerTo();
+  ArgTypes[FirstIRArg] = LTy->getPointerTo(
+  CGM.getDataLayout().getAllocaAddrSpace());
   break;
 }
 


Index: test/CodeGenOpenCL/byval.cl
===
--- /dev/null
+++ test/CodeGenOpenCL/byval.cl
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn %s | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - -triple amdgcn---amdgizcl %s | FileCheck %s -check-prefix=AMDGIZ
+
+struct A {
+  int x[100];
+};
+
+int f(struct A a);
+
+int g() {
+  struct A a;
+  // CHECK: call i32 @f(%struct.A* byval{{.*}}%a)
+  // AMDGIZ: call i32 @f(%struct.A addrspace(5)* byval{{.*}}%a)
+  return f(a);
+}
+
+// CHECK: declare i32 @f(%struct.A* byval{{.*}})
+// AMDGIZ: declare i32 @f(%struct.A addrspace(5)* byval{{.*}})
Index: lib/CodeGen/CGCall.cpp
===
--- lib/CodeGen/CGCall.cpp
+++ lib/CodeGen/CGCall.cpp
@@ -1586,9 +1586,10 @@
 
 case ABIArgInfo::Indirect: {
   assert(NumIRArgs == 1);
-  // indirect arguments are always on the stack, which is addr space #0.
+  // indirect arguments are always on the stack, which is alloca addr space.
   llvm::Type *LTy = ConvertTypeForMem(it->type);
-  ArgTypes[FirstIRArg] = LTy->getPointerTo();
+  ArgTypes[FirstIRArg] = LTy->getPointerTo(
+  CGM.getDataLayout().getAllocaAddrSpace());
   break;
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D31830: Emit invariant.group.barrier when using union field

2017-04-17 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: lib/CodeGen/CGExpr.cpp:3517
+CGM.getCodeGenOpts().StrictVTablePointers &&
+CGM.getCodeGenOpts().OptimizationLevel > 0)
+  addr = Address(Builder.CreateInvariantGroupBarrier(addr.getPointer()),

Prazek wrote:
> rjmccall wrote:
> > Checking for v-table pointers recursively isn't really that difficult, but 
> > if you really don't want to do that, please at least check for non-POD-ness 
> > or something so that this isn't kicking in for literally every struct type.
> ok, I am also planning to fix this in the later patch, because the same 
> problem arise when comparing 2 pointers to dynamic classe. 
> I would like to have a bit in CXXRecordDecl to remember if it has any vptr 
> inside that would calculate durring the construction. 
> My biggest fear is that if I won't cache it then it will be very slow.
We could repeat this work from scratch on every single union field access done 
by IRGen and it would still be way, way faster than doing anything extra on 
every record definition in the program.  The latter is done orders of magnitude 
more frequently than the former.


https://reviews.llvm.org/D31830



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


[PATCH] D31869: Register isStaticStorageClass matcher

2017-04-17 Thread Dave Lee via Phabricator via cfe-commits
kastiglione added a comment.

thanks @aaron.ballman :)


https://reviews.llvm.org/D31869



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


[PATCH] D32043: [Driver] Load all necessary default sanitizer blacklists

2017-04-17 Thread Evgeniy Stepanov via Phabricator via cfe-commits
eugenis added a comment.

Looks fine.


https://reviews.llvm.org/D32043



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


[PATCH] D32043: [Driver] Load all necessary default sanitizer blacklists

2017-04-17 Thread Peter Collingbourne via Phabricator via cfe-commits
pcc added a comment.

This seems reasonable to me, although it's unfortunate that the design of the 
sanitizer blacklist feature does not (at present) allow different blacklists 
for different sanitizers.

@eugenis what do you think?


https://reviews.llvm.org/D32043



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


[PATCH] D32132: [AArch64][clang] Pass cpu/arch information to assembler for AArch64.

2017-04-17 Thread Manoj Gupta via Phabricator via cfe-commits
manojgupta created this revision.
Herald added subscribers: rengolin, aemerson.

Pass Cpu/Arch options to assembler for AArch64 with no-integrated-as.
This fixes PR20019.


https://reviews.llvm.org/D32132

Files:
  lib/Driver/ToolChains/Gnu.cpp
  test/Driver/linux-as.c


Index: test/Driver/linux-as.c
===
--- test/Driver/linux-as.c
+++ test/Driver/linux-as.c
@@ -100,6 +100,33 @@
 // RUN:   | FileCheck -check-prefix=CHECK-ARM-HARDFP %s
 // CHECK-ARM-HARDFP: as{{(.exe)?}}" "-mfloat-abi=hard"
 //
+// RUN: %clang -target aarch64-linux-gnu -mcpu=cortex-a53 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-MCPU %s
+// CHECK-ARM64-MCPU: as{{(.exe)?}}" "-mcpu=cortex-a53"
+//
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-MARCH %s
+// CHECK-ARM64-MARCH: as{{(.exe)?}}" "-march=armv8-a"
+//
+// RUN: %clang -target aarch64-linux-gnu -mcpu=cortex-a53 -march=armv8-a -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-ALL %s
+// CHECK-ARM64-ALL: as{{(.exe)?}}" "-march=armv8-a" "-mcpu=cortex-a53"
+//
+// RUN: %clang -target aarch64_be-linux-gnu -mcpu=cortex-a53 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-MCPU %s
+//
+// RUN: %clang -target aarch64_be-linux-gnu -march=armv8-a -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-MARCH %s
+//
+// RUN: %clang -target aarch64_be-linux-gnu -mcpu=cortex-a53 -march=armv8-a 
-### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-ALL %s
+//
 // RUN: %clang -target ppc-linux -mcpu=invalid-cpu -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-PPC-NO-MCPU %s
Index: lib/Driver/ToolChains/Gnu.cpp
===
--- lib/Driver/ToolChains/Gnu.cpp
+++ lib/Driver/ToolChains/Gnu.cpp
@@ -770,6 +770,12 @@
 Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
 break;
   }
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be: {
+Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
+Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
+break;
+  }
   case llvm::Triple::mips:
   case llvm::Triple::mipsel:
   case llvm::Triple::mips64:


Index: test/Driver/linux-as.c
===
--- test/Driver/linux-as.c
+++ test/Driver/linux-as.c
@@ -100,6 +100,33 @@
 // RUN:   | FileCheck -check-prefix=CHECK-ARM-HARDFP %s
 // CHECK-ARM-HARDFP: as{{(.exe)?}}" "-mfloat-abi=hard"
 //
+// RUN: %clang -target aarch64-linux-gnu -mcpu=cortex-a53 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-MCPU %s
+// CHECK-ARM64-MCPU: as{{(.exe)?}}" "-mcpu=cortex-a53"
+//
+// RUN: %clang -target aarch64-linux-gnu -march=armv8-a -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-MARCH %s
+// CHECK-ARM64-MARCH: as{{(.exe)?}}" "-march=armv8-a"
+//
+// RUN: %clang -target aarch64-linux-gnu -mcpu=cortex-a53 -march=armv8-a -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-ALL %s
+// CHECK-ARM64-ALL: as{{(.exe)?}}" "-march=armv8-a" "-mcpu=cortex-a53"
+//
+// RUN: %clang -target aarch64_be-linux-gnu -mcpu=cortex-a53 -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-MCPU %s
+//
+// RUN: %clang -target aarch64_be-linux-gnu -march=armv8-a -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-MARCH %s
+//
+// RUN: %clang -target aarch64_be-linux-gnu -mcpu=cortex-a53 -march=armv8-a -### \
+// RUN:   -no-integrated-as -c %s 2>&1 \
+// RUN:   | FileCheck -check-prefix=CHECK-ARM64-ALL %s
+//
 // RUN: %clang -target ppc-linux -mcpu=invalid-cpu -### \
 // RUN:   -no-integrated-as -c %s 2>&1 \
 // RUN:   | FileCheck -check-prefix=CHECK-PPC-NO-MCPU %s
Index: lib/Driver/ToolChains/Gnu.cpp
===
--- lib/Driver/ToolChains/Gnu.cpp
+++ lib/Driver/ToolChains/Gnu.cpp
@@ -770,6 +770,12 @@
 Args.AddLastArg(CmdArgs, options::OPT_mfpu_EQ);
 break;
   }
+  case llvm::Triple::aarch64:
+  case llvm::Triple::aarch64_be: {
+Args.AddLastArg(CmdArgs, options::OPT_march_EQ);
+Args.AddLastArg(CmdArgs, options::OPT_mcpu_EQ);
+break;
+  }
   case llvm::Triple::mips:
   case llvm::Triple::mipsel:
   case llvm::Triple::mips64:
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32035: [OpenMP] Error when trying to offload to an unsupported architecture

2017-04-17 Thread Alexey Bataev via Phabricator via cfe-commits
ABataev accepted this revision.
ABataev added a comment.
This revision is now accepted and ready to land.

LG


Repository:
  rL LLVM

https://reviews.llvm.org/D32035



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


[PATCH] D32035: [OpenMP] Error when trying to offload to an unsupported architecture

2017-04-17 Thread Gheorghe-Teodor Bercea via Phabricator via cfe-commits
gtbercea updated this revision to Diff 95461.
gtbercea added a comment.

Merge IF statements.


Repository:
  rL LLVM

https://reviews.llvm.org/D32035

Files:
  lib/Frontend/CompilerInvocation.cpp
  test/OpenMP/target_messages.cpp


Index: test/OpenMP/target_messages.cpp
===
--- test/OpenMP/target_messages.cpp
+++ test/OpenMP/target_messages.cpp
@@ -4,6 +4,8 @@
 // RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx64-nvidia-cuda -o - %s 
2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s
 // RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx-nvidia-cuda -o - %s 
2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s
 // CHECK-UNSUPPORTED-HOST-TARGET: error: The target 
'{{nvptx64-nvidia-cuda|nvptx-nvidia-cuda}}' is not a supported OpenMP host 
target.
+// RUN: not %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=hexagon-linux-gnu 
-o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-DEVICE-TARGET %s
+// CHECK-UNSUPPORTED-DEVICE-TARGET: OpenMP target is invalid: 
'hexagon-linux-gnu'
 
 void foo() {
 }
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2239,7 +2239,14 @@
 for (unsigned i = 0; i < A->getNumValues(); ++i) {
   llvm::Triple TT(A->getValue(i));
 
-  if (TT.getArch() == llvm::Triple::UnknownArch)
+  if (TT.getArch() == llvm::Triple::UnknownArch ||
+  !(TT.getArch() == llvm::Triple::ppc ||
+TT.getArch() == llvm::Triple::ppc64 ||
+TT.getArch() == llvm::Triple::ppc64le ||
+TT.getArch() == llvm::Triple::nvptx ||
+TT.getArch() == llvm::Triple::nvptx64 ||
+TT.getArch() == llvm::Triple::x86 ||
+TT.getArch() == llvm::Triple::x86_64))
 Diags.Report(clang::diag::err_drv_invalid_omp_target) << 
A->getValue(i);
   else
 Opts.OMPTargetTriples.push_back(TT);


Index: test/OpenMP/target_messages.cpp
===
--- test/OpenMP/target_messages.cpp
+++ test/OpenMP/target_messages.cpp
@@ -4,6 +4,8 @@
 // RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx64-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s
 // RUN: not %clang_cc1 -fopenmp -std=c++11 -triple nvptx-nvidia-cuda -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-HOST-TARGET %s
 // CHECK-UNSUPPORTED-HOST-TARGET: error: The target '{{nvptx64-nvidia-cuda|nvptx-nvidia-cuda}}' is not a supported OpenMP host target.
+// RUN: not %clang_cc1 -fopenmp -std=c++11 -fopenmp-targets=hexagon-linux-gnu -o - %s 2>&1 | FileCheck --check-prefix CHECK-UNSUPPORTED-DEVICE-TARGET %s
+// CHECK-UNSUPPORTED-DEVICE-TARGET: OpenMP target is invalid: 'hexagon-linux-gnu'
 
 void foo() {
 }
Index: lib/Frontend/CompilerInvocation.cpp
===
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2239,7 +2239,14 @@
 for (unsigned i = 0; i < A->getNumValues(); ++i) {
   llvm::Triple TT(A->getValue(i));
 
-  if (TT.getArch() == llvm::Triple::UnknownArch)
+  if (TT.getArch() == llvm::Triple::UnknownArch ||
+  !(TT.getArch() == llvm::Triple::ppc ||
+TT.getArch() == llvm::Triple::ppc64 ||
+TT.getArch() == llvm::Triple::ppc64le ||
+TT.getArch() == llvm::Triple::nvptx ||
+TT.getArch() == llvm::Triple::nvptx64 ||
+TT.getArch() == llvm::Triple::x86 ||
+TT.getArch() == llvm::Triple::x86_64))
 Diags.Report(clang::diag::err_drv_invalid_omp_target) << A->getValue(i);
   else
 Opts.OMPTargetTriples.push_back(TT);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32084: AMDGPU/GFX9: Set +fast-fmaf for >=gfx900 unless -cl-denorms-are-zero is set

2017-04-17 Thread Konstantin Zhuravlyov via Phabricator via cfe-commits
kzhuravl added a comment.

Ping.


https://reviews.llvm.org/D32084



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


Re: Canonical param types and restrict array index qualifiers

2017-04-17 Thread Aaron Ballman via cfe-commits
On Mon, Apr 17, 2017 at 2:14 PM, Richard Smith  wrote:
> C11 6.7.6.3p15: "In the determination of type compatibility and of a
> composite type, each parameter declared with function or array type is taken
> as having the adjusted type and each parameter declared with qualified type
> is taken as having the unqualified version of its declared type."
>
> So "int f(int p[restrict])" is compatible with "int f(int *restrict p)" and
> "int f(int *p)", so getCanonicalParamType should be stripping the qualifiers
> (if any) added by getArrayDecayedType -- or not adding them in the first
> place. Seems like the same bug exists for "int f(int p[const])" and "int
> f(int p[volatile])" too.
>
> An even more broken case along the same codepath is the bizarre construct
> "int f(int arr[_Nullable])". The canonical function type should not include
> the nullability attribute (it's not even part of the canonical parameter
> type), but currently it does! Our current handling for this case is clearly
> wrong: getCanonicalParamType returns a CanQualType wrapping an
> AttributedType, which is not a canonical type.
>
> Maybe the easiest fix would be to make getCanonicalParamType just build the
> type "pointer to array element type" and not call getArrayDecayedType at
> all, since it doesn't want any of the other things that getArrayDecayedType
> does.

I'm happy to make that change, however, I'm struggling to devise a
good test case that doesn't rely on my out-of-tree code to demonstrate
the problem. Do you happen to have a reasonable test case for me to
work from?

~Aaron

>
> On 17 April 2017 at 10:07, Aaron Ballman via cfe-commits
>  wrote:
>>
>> I've run into a case where I am calling ASTContext::getFunctionType()
>> and getting a failed assertion because a parameter we thought we
>> canonicalized isn't actually canonical. The function is declared as:
>>
>> extern int regexec (int __pmatch[__restrict]);
>>
>> When we call getCanonicalParamType() on that parameter, it results in
>> a type that is a decayed pointer that still has the restrict
>> qualifier, because getArrayDecayedType() leaves on index type
>> qualifiers. However, isCanonicalAsParam() checks for the presence of
>> any local qualifiers and returns false if any are present. This
>> results in the assertion failing.
>>
>> I believe this is a bug, but I'm not certain where. Should
>> getCanonicalParamType() be stripping the restrict array index
>> qualifier? Should isCanonicalAsParam() be modified? Or is something
>> else going on that I'm not quite understanding?
>>
>> Thanks!
>>
>> ~Aaron
>> ___
>> cfe-commits mailing list
>> cfe-commits@lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: Canonical param types and restrict array index qualifiers

2017-04-17 Thread Richard Smith via cfe-commits
C11 6.7.6.3p15: "In the determination of type compatibility and of a
composite type, each parameter declared with function or array type is
taken as having the adjusted type and each parameter declared with
qualified type is taken as having the unqualified version of its declared
type."

So "int f(int p[restrict])" is compatible with "int f(int *restrict p)" and
"int f(int *p)", so getCanonicalParamType should be stripping the
qualifiers (if any) added by getArrayDecayedType -- or not adding them in
the first place. Seems like the same bug exists for "int f(int p[const])"
and "int f(int p[volatile])" too.

An even more broken case along the same codepath is the bizarre construct
"int f(int arr[_Nullable])". The canonical function type should not include
the nullability attribute (it's not even part of the canonical parameter
type), but currently it does! Our current handling for this case is clearly
wrong: getCanonicalParamType returns a CanQualType wrapping an
AttributedType, which is not a canonical type.

Maybe the easiest fix would be to make getCanonicalParamType just build the
type "pointer to array element type" and not call getArrayDecayedType at
all, since it doesn't want any of the other things that getArrayDecayedType
does.

On 17 April 2017 at 10:07, Aaron Ballman via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> I've run into a case where I am calling ASTContext::getFunctionType()
> and getting a failed assertion because a parameter we thought we
> canonicalized isn't actually canonical. The function is declared as:
>
> extern int regexec (int __pmatch[__restrict]);
>
> When we call getCanonicalParamType() on that parameter, it results in
> a type that is a decayed pointer that still has the restrict
> qualifier, because getArrayDecayedType() leaves on index type
> qualifiers. However, isCanonicalAsParam() checks for the presence of
> any local qualifiers and returns false if any are present. This
> results in the assertion failing.
>
> I believe this is a bug, but I'm not certain where. Should
> getCanonicalParamType() be stripping the restrict array index
> qualifier? Should isCanonicalAsParam() be modified? Or is something
> else going on that I'm not quite understanding?
>
> Thanks!
>
> ~Aaron
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r300461 - Use default ref capture to simplify local lambdas, use a template to avoid std::function overhead, other cleanup

2017-04-17 Thread David Blaikie via cfe-commits
Author: dblaikie
Date: Mon Apr 17 12:16:19 2017
New Revision: 300461

URL: http://llvm.org/viewvc/llvm-project?rev=300461=rev
Log:
Use default ref capture to simplify local lambdas, use a template to avoid 
std::function overhead, other cleanup

Modified:
cfe/trunk/lib/AST/ExternalASTMerger.cpp

Modified: cfe/trunk/lib/AST/ExternalASTMerger.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExternalASTMerger.cpp?rev=300461=300460=300461=diff
==
--- cfe/trunk/lib/AST/ExternalASTMerger.cpp (original)
+++ cfe/trunk/lib/AST/ExternalASTMerger.cpp Mon Apr 17 12:16:19 2017
@@ -89,25 +89,21 @@ bool IsForwardDeclaration(Decl *D) {
   }
 }
 
+template 
 void ForEachMatchingDC(
 const DeclContext *DC,
 llvm::ArrayRef Importers,
-std::function
-Callback) {
+CallbackType Callback) {
   for (const ExternalASTMerger::ImporterPair  : Importers) {
-Source SourceTU(
-IP.Forward->getFromContext().getTranslationUnitDecl());
-Source SourceDC =
-LookupSameContext(SourceTU, DC, *IP.Reverse);
-if (SourceDC.get()) {
+Source SourceTU =
+IP.Forward->getFromContext().getTranslationUnitDecl();
+if (auto SourceDC = LookupSameContext(SourceTU, DC, *IP.Reverse))
   Callback(IP, SourceDC);
-}
   }
 }
 
 bool HasDeclOfSameType(llvm::ArrayRef Decls, const Candidate ) {
-  return std::any_of(Decls.begin(), Decls.end(), [](const Candidate ) {
+  return llvm::any_of(Decls, [&](const Candidate ) {
 return C.first.get()->getKind() == D.first.get()->getKind();
   });
 }
@@ -139,15 +135,15 @@ bool ExternalASTMerger::FindExternalVisi
 }
   };
 
-  ForEachMatchingDC(DC, Importers, [Name, ](
-   const ImporterPair ,
-   Source SourceDC) {
-DeclarationName FromName = IP.Reverse->Import(Name);
-DeclContextLookupResult Result = SourceDC.get()->lookup(FromName);
-for (NamedDecl *FromD : Result) {
-  FilterFoundDecl(std::make_pair(FromD, IP.Forward.get()));
-}
-  });
+  ForEachMatchingDC(
+  DC, Importers,
+  [&](const ImporterPair , Source SourceDC) {
+DeclarationName FromName = IP.Reverse->Import(Name);
+DeclContextLookupResult Result = SourceDC.get()->lookup(FromName);
+for (NamedDecl *FromD : Result) {
+  FilterFoundDecl(std::make_pair(FromD, IP.Forward.get()));
+}
+  });
 
   llvm::ArrayRef DeclsToReport =
   CompleteDecls.empty() ? ForwardDecls : CompleteDecls;
@@ -170,15 +166,14 @@ void ExternalASTMerger::FindExternalLexi
 const DeclContext *DC, llvm::function_ref IsKindWeWant,
 SmallVectorImpl ) {
   ForEachMatchingDC(
-  DC, Importers, [DC, IsKindWeWant](const ImporterPair ,
-Source SourceDC) {
+  DC, Importers,
+  [&](const ImporterPair , Source SourceDC) {
 for (const Decl *SourceDecl : SourceDC.get()->decls()) {
   if (IsKindWeWant(SourceDecl->getKind())) {
 Decl *ImportedDecl =
 IP.Forward->Import(const_cast(SourceDecl));
 assert(ImportedDecl->getDeclContext() == DC);
 (void)ImportedDecl;
-(void)DC;
   }
 }
   });


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


[PATCH] D31830: Emit invariant.group.barrier when using union field

2017-04-17 Thread Piotr Padlewski via Phabricator via cfe-commits
Prazek added inline comments.



Comment at: lib/CodeGen/CGExpr.cpp:3517
+CGM.getCodeGenOpts().StrictVTablePointers &&
+CGM.getCodeGenOpts().OptimizationLevel > 0)
+  addr = Address(Builder.CreateInvariantGroupBarrier(addr.getPointer()),

rjmccall wrote:
> Checking for v-table pointers recursively isn't really that difficult, but if 
> you really don't want to do that, please at least check for non-POD-ness or 
> something so that this isn't kicking in for literally every struct type.
ok, I am also planning to fix this in the later patch, because the same problem 
arise when comparing 2 pointers to dynamic classe. 
I would like to have a bit in CXXRecordDecl to remember if it has any vptr 
inside that would calculate durring the construction. 
My biggest fear is that if I won't cache it then it will be very slow.


https://reviews.llvm.org/D31830



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


Re: r300145 - ExternalASTMerger.cpp: Silence another warning. [-Wunused-lambda-capture]

2017-04-17 Thread David Blaikie via cfe-commits
I'll change this to [&] capture - any lambda that doesn't escape it's scope
should generally use [&] & that'll avoid the need for explicitly discarding
conditionally unused captures, etc.

On Wed, Apr 12, 2017 at 5:45 PM NAKAMURA Takumi via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> Author: chapuni
> Date: Wed Apr 12 19:17:28 2017
> New Revision: 300145
>
> URL: http://llvm.org/viewvc/llvm-project?rev=300145=rev
> Log:
> ExternalASTMerger.cpp: Silence another warning. [-Wunused-lambda-capture]
>
> Modified:
> cfe/trunk/lib/AST/ExternalASTMerger.cpp
>
> Modified: cfe/trunk/lib/AST/ExternalASTMerger.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExternalASTMerger.cpp?rev=300145=300144=300145=diff
>
> ==
> --- cfe/trunk/lib/AST/ExternalASTMerger.cpp (original)
> +++ cfe/trunk/lib/AST/ExternalASTMerger.cpp Wed Apr 12 19:17:28 2017
> @@ -178,6 +178,7 @@ void ExternalASTMerger::FindExternalLexi
>  IP.Forward->Import(const_cast(SourceDecl));
>  assert(ImportedDecl->getDeclContext() == DC);
>  (void)ImportedDecl;
> +(void)DC;
>}
>  }
>});
>
>
> ___
> cfe-commits mailing list
> cfe-commits@lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Canonical param types and restrict array index qualifiers

2017-04-17 Thread Aaron Ballman via cfe-commits
I've run into a case where I am calling ASTContext::getFunctionType()
and getting a failed assertion because a parameter we thought we
canonicalized isn't actually canonical. The function is declared as:

extern int regexec (int __pmatch[__restrict]);

When we call getCanonicalParamType() on that parameter, it results in
a type that is a decayed pointer that still has the restrict
qualifier, because getArrayDecayedType() leaves on index type
qualifiers. However, isCanonicalAsParam() checks for the presence of
any local qualifiers and returns false if any are present. This
results in the assertion failing.

I believe this is a bug, but I'm not certain where. Should
getCanonicalParamType() be stripping the restrict array index
qualifier? Should isCanonicalAsParam() be modified? Or is something
else going on that I'm not quite understanding?

Thanks!

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


[PATCH] D31646: [coroutines] Build GRO declaration and return GRO statement

2017-04-17 Thread Gor Nishanov via Phabricator via cfe-commits
GorNishanov added a comment.

Melodic ping


https://reviews.llvm.org/D31646



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


[PATCH] D31830: Emit invariant.group.barrier when using union field

2017-04-17 Thread John McCall via Phabricator via cfe-commits
rjmccall added inline comments.



Comment at: lib/CodeGen/CGExpr.cpp:3517
+CGM.getCodeGenOpts().StrictVTablePointers &&
+CGM.getCodeGenOpts().OptimizationLevel > 0)
+  addr = Address(Builder.CreateInvariantGroupBarrier(addr.getPointer()),

Checking for v-table pointers recursively isn't really that difficult, but if 
you really don't want to do that, please at least check for non-POD-ness or 
something so that this isn't kicking in for literally every struct type.


https://reviews.llvm.org/D31830



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


r300454 - [ObjC] Mark loads from __NSArray0 and __NSDictionary0 as invariant.load.

2017-04-17 Thread Akira Hatanaka via cfe-commits
Author: ahatanak
Date: Mon Apr 17 10:21:55 2017
New Revision: 300454

URL: http://llvm.org/viewvc/llvm-project?rev=300454=rev
Log:
[ObjC] Mark loads from __NSArray0 and __NSDictionary0 as invariant.load.

Also, simplify code by calling MakeNaturalAlignAddrLValue.

This is a follow-up to r300396.

Modified:
cfe/trunk/lib/CodeGen/CGObjC.cpp
cfe/trunk/test/CodeGenObjC/empty-collection-literals.m

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=300454=300453=300454=diff
==
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Mon Apr 17 10:21:55 2017
@@ -126,10 +126,12 @@ llvm::Value *CodeGenFunction::EmitObjCCo
 QualType IdTy(CGM.getContext().getObjCIdType());
 llvm::Constant *Constant =
 CGM.CreateRuntimeVariable(ConvertType(IdTy), ConstantName);
-Address Addr(Constant, Context.getTypeAlignInChars(IdTy));
-LValue LV = MakeAddrLValue(Addr, IdTy);
-return Builder.CreateBitCast(EmitLoadOfScalar(LV, E->getLocStart()),
- ConvertType(E->getType()));
+LValue LV = MakeNaturalAlignAddrLValue(Constant, IdTy);
+llvm::Value *Ptr = EmitLoadOfScalar(LV, E->getLocStart());
+cast(Ptr)->setMetadata(
+CGM.getModule().getMDKindID("invariant.load"),
+llvm::MDNode::get(getLLVMContext(), None));
+return Builder.CreateBitCast(Ptr, ConvertType(E->getType()));
   }
 
   // Compute the type of the array we're initializing.

Modified: cfe/trunk/test/CodeGenObjC/empty-collection-literals.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/empty-collection-literals.m?rev=300454=300453=300454=diff
==
--- cfe/trunk/test/CodeGenObjC/empty-collection-literals.m (original)
+++ cfe/trunk/test/CodeGenObjC/empty-collection-literals.m Mon Apr 17 10:21:55 
2017
@@ -41,7 +41,7 @@ void test_empty_dictionary() {
 
   // CHECK-WITH-EMPTY-COLLECTIONS-LABEL: define void @test_empty_dictionary
   // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void
-  // CHECK-WITH-EMPTY-COLLECTIONS: load {{.*}} @__NSDictionary0__
+  // CHECK-WITH-EMPTY-COLLECTIONS: load {{.*}} 
@__NSDictionary0__{{.*}}!invariant.load
   // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void
   // CHECK-WITH-EMPTY-COLLECTIONS: {{call.*objc_retain\(}}
   // CHECK-WITH-EMPTY-COLLECTIONS-NOT: ret void


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


[PATCH] D31717: CodeGen: Let lifetime intrinsic use alloca address space

2017-04-17 Thread John McCall via Phabricator via cfe-commits
rjmccall accepted this revision.
rjmccall added a comment.

LGTM.


https://reviews.llvm.org/D31717



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


[PATCH] D29827: [AVR] Add -mmcu option to the driver

2017-04-17 Thread Jonathan Roelofs via Phabricator via cfe-commits
jroelofs accepted this revision.
jroelofs added a comment.
This revision is now accepted and ready to land.

LGTM




Comment at: include/clang/Driver/Options.td:1613
 def mcpu_EQ : Joined<["-"], "mcpu=">, Group;
+def mmcu_EQ : Joined<["-"], "mmcu=">, Group;
 def mdynamic_no_pic : Joined<["-"], "mdynamic-no-pic">, Group;

Lekensteyn wrote:
> dylanmckay wrote:
> > Lekensteyn wrote:
> > > jroelofs wrote:
> > > > Would it make sense to have mcu be an alias for mcpu instead?
> > > That would deviate from the GCC interface, so I have chosen for the 
> > > current situation:
> > > ```
> > > $ avr-gcc -mmcu=avr2 -o /dev/null x.c
> > > $ avr-gcc -mcpu=avr2 -o /dev/null x.c
> > > avr-gcc: error: unrecognized command line option '-mcpu=avr2'
> > > $ avr-gcc -march=avr2 -o /dev/null x.c
> > > avr-gcc: error: unrecognized command line option '-march=avr2'
> > > $ avr-gcc -v
> > > ...
> > > gcc version 6.3.0 (GCC)
> > > ```
> > I think @jroelofs  means that it is possible to make `mmcu` an alias of 
> > `mmcu` internally. This would mean we wouldn't need to add AVR-specific 
> > `getCPUName` handling.
> If mmcu is made an alias of mcpu, wouldn't that mean that both `-mcpu` and 
> `-mmcu` would be accepted by driver (undesirable)?
> As far as I can see, `-target-cpu` must be passed to the frontend and 
> assembler, `-mcpu=` is not recognized as option. And ensuring that 
> `getCPUName` returns a non-empty string ensures that `-target-cpu` is passed.
> 
> I am quite new to the internals, so please let me know if I misunderstood 
> something :-)
-mmcu= is the right thing to do, without the alias (I was wrong).


https://reviews.llvm.org/D29827



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


[libcxx] r300451 - Sigh. Once again forgot about the 'no exceptions' bots.

2017-04-17 Thread Marshall Clow via cfe-commits
Author: marshall
Date: Mon Apr 17 09:18:44 2017
New Revision: 300451

URL: http://llvm.org/viewvc/llvm-project?rev=300451=rev
Log:
Sigh. Once again forgot about the 'no exceptions' bots.

Modified:

libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp

libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp

Modified: 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp?rev=300451=300450=300451=diff
==
--- 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
 Mon Apr 17 09:18:44 2017
@@ -18,6 +18,7 @@
 #include "min_allocator.h"
 #include "asan_testing.h"
 
+#ifndef TEST_HAS_NO_EXCEPTIONS
 struct Throws {
 Throws() : v_(0) {}
 Throws(int v) : v_(v) {}
@@ -30,6 +31,7 @@ struct Throws {
 };
 
 bool Throws::sThrows = false;
+#endif
 
 int main()
 {
@@ -85,6 +87,7 @@ int main()
 assert(is_contiguous_container_asan_correct(l1));
 }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
 // Test for LWG2853:
 // Throws: Nothing unless an exception is thrown by the assignment operator or 
move assignment operator of T.
 {
@@ -96,4 +99,5 @@ int main()
 v.erase(v.begin());
 assert(v.size() == 0);
 }
+#endif
 }

Modified: 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp?rev=300451=300450=300451=diff
==
--- 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
 Mon Apr 17 09:18:44 2017
@@ -18,6 +18,7 @@
 #include "min_allocator.h"
 #include "asan_testing.h"
 
+#ifndef TEST_HAS_NO_EXCEPTIONS
 struct Throws {
 Throws() : v_(0) {}
 Throws(int v) : v_(v) {}
@@ -30,6 +31,7 @@ struct Throws {
 };
 
 bool Throws::sThrows = false;
+#endif
 
 int main()
 {
@@ -138,6 +140,7 @@ int main()
 assert(is_contiguous_container_asan_correct(outer[1]));
 }
 #endif
+#ifndef TEST_HAS_NO_EXCEPTIONS
 // Test for LWG2853:
 // Throws: Nothing unless an exception is thrown by the assignment operator or 
move assignment operator of T.
 {
@@ -149,4 +152,5 @@ int main()
 v.erase(v.begin(), v.end());
 assert(v.size() == 0);
 }
+#endif
 }


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


[PATCH] D32113: Add path from clang to doxygen document include header

2017-04-17 Thread Yuka Takahashi via Phabricator via cfe-commits
yamaguchi updated this revision to Diff 95436.
yamaguchi added a comment.

This will generate #include "clang/Sema/Sema.h" .


https://reviews.llvm.org/D32113

Files:
  docs/doxygen.cfg.in


Index: docs/doxygen.cfg.in
===
--- docs/doxygen.cfg.in
+++ docs/doxygen.cfg.in
@@ -132,7 +132,7 @@
 # shortest path that makes the file name unique will be used
 # The default value is: YES.
 
-FULL_PATH_NAMES= NO
+FULL_PATH_NAMES= YES
 
 # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
 # Stripping is only done if one of the specified strings matches the left-hand
@@ -144,16 +144,16 @@
 # will be relative from the directory where doxygen is started.
 # This tag requires that the tag FULL_PATH_NAMES is set to YES.
 
-STRIP_FROM_PATH= ../..
+STRIP_FROM_PATH= @abs_srcdir@/..
 
 # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
 # path mentioned in the documentation of a class, which tells the reader which
 # header file to include in order to use a class. If left blank only the name 
of
 # the header file containing the class definition is used. Otherwise one should
 # specify the list of include paths that are normally passed to the compiler
 # using the -I flag.
 
-STRIP_FROM_INC_PATH=
+STRIP_FROM_INC_PATH= @abs_srcdir@/../include
 
 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
 # less readable) file names. This can be useful is your file systems doesn't
@@ -513,7 +513,7 @@
 # files with double quotes in the documentation rather than with sharp 
brackets.
 # The default value is: NO.
 
-FORCE_LOCAL_INCLUDES   = NO
+FORCE_LOCAL_INCLUDES   = YES
 
 # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
 # documentation for inline members.


Index: docs/doxygen.cfg.in
===
--- docs/doxygen.cfg.in
+++ docs/doxygen.cfg.in
@@ -132,7 +132,7 @@
 # shortest path that makes the file name unique will be used
 # The default value is: YES.
 
-FULL_PATH_NAMES= NO
+FULL_PATH_NAMES= YES
 
 # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
 # Stripping is only done if one of the specified strings matches the left-hand
@@ -144,16 +144,16 @@
 # will be relative from the directory where doxygen is started.
 # This tag requires that the tag FULL_PATH_NAMES is set to YES.
 
-STRIP_FROM_PATH= ../..
+STRIP_FROM_PATH= @abs_srcdir@/..
 
 # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
 # path mentioned in the documentation of a class, which tells the reader which
 # header file to include in order to use a class. If left blank only the name of
 # the header file containing the class definition is used. Otherwise one should
 # specify the list of include paths that are normally passed to the compiler
 # using the -I flag.
 
-STRIP_FROM_INC_PATH=
+STRIP_FROM_INC_PATH= @abs_srcdir@/../include
 
 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
 # less readable) file names. This can be useful is your file systems doesn't
@@ -513,7 +513,7 @@
 # files with double quotes in the documentation rather than with sharp brackets.
 # The default value is: NO.
 
-FORCE_LOCAL_INCLUDES   = NO
+FORCE_LOCAL_INCLUDES   = YES
 
 # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
 # documentation for inline members.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32113: Add path from clang to doxygen document include header

2017-04-17 Thread Raphael Isemann via Phabricator via cfe-commits
teemperor added inline comments.



Comment at: docs/doxygen.cfg.in:158
+STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang
+STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang-c
 

yamaguchi wrote:
> v.g.vassilev wrote:
> > We should be stripping `@abs_srcdir@/../include` because in reality the way 
> > the user will include those files is via `#include "clang/Sema/Sema.h" for 
> > instance.
> Do you mean we should be stripping 
> ```
> @abs_srcdir@/../include
> ```
> rather than
> 
> ```
> @abs_srcdir@/..
> @abs_srcdir@/../include/clang
> @abs_srcdir@/../include/clang-c
> ```
> ?
Yes, I think so.


https://reviews.llvm.org/D32113



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


[libcxx] r300449 - Mark LWG#2853 as complete. No code changes required, but added a couple of extra tests

2017-04-17 Thread Marshall Clow via cfe-commits
Author: marshall
Date: Mon Apr 17 08:19:14 2017
New Revision: 300449

URL: http://llvm.org/viewvc/llvm-project?rev=300449=rev
Log:
Mark LWG#2853 as complete. No code changes required, but added a couple of 
extra tests

Modified:

libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp

libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
libcxx/trunk/www/cxx1z_status.html

Modified: 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp?rev=300449=300448=300449=diff
==
--- 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter.pass.cpp
 Mon Apr 17 08:19:14 2017
@@ -18,6 +18,19 @@
 #include "min_allocator.h"
 #include "asan_testing.h"
 
+struct Throws {
+Throws() : v_(0) {}
+Throws(int v) : v_(v) {}
+Throws(const Throws  ) : v_(rhs.v_) { if (sThrows) throw 1; }
+Throws(  Throws &) : v_(rhs.v_) { if (sThrows) throw 1; }
+Throws& operator=(const Throws  ) { v_ = rhs.v_; return *this; }
+Throws& operator=(  Throws &) { v_ = rhs.v_; return *this; }
+int v_;
+static bool sThrows;
+};
+
+bool Throws::sThrows = false;
+
 int main()
 {
 {
@@ -72,4 +85,15 @@ int main()
 assert(is_contiguous_container_asan_correct(l1));
 }
 #endif
+// Test for LWG2853:
+// Throws: Nothing unless an exception is thrown by the assignment operator or 
move assignment operator of T.
+{
+Throws arr[] = {1, 2, 3};
+std::vector v(arr, arr+3);
+Throws::sThrows = true;
+v.erase(v.begin());
+v.erase(--v.end());
+v.erase(v.begin());
+assert(v.size() == 0);
+}
 }

Modified: 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp?rev=300449=300448=300449=diff
==
--- 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/containers/sequences/vector/vector.modifiers/erase_iter_iter.pass.cpp
 Mon Apr 17 08:19:14 2017
@@ -18,6 +18,19 @@
 #include "min_allocator.h"
 #include "asan_testing.h"
 
+struct Throws {
+Throws() : v_(0) {}
+Throws(int v) : v_(v) {}
+Throws(const Throws  ) : v_(rhs.v_) { if (sThrows) throw 1; }
+Throws(  Throws &) : v_(rhs.v_) { if (sThrows) throw 1; }
+Throws& operator=(const Throws  ) { v_ = rhs.v_; return *this; }
+Throws& operator=(  Throws &) { v_ = rhs.v_; return *this; }
+int v_;
+static bool sThrows;
+};
+
+bool Throws::sThrows = false;
+
 int main()
 {
 int a1[] = {1, 2, 3};
@@ -125,4 +138,15 @@ int main()
 assert(is_contiguous_container_asan_correct(outer[1]));
 }
 #endif
+// Test for LWG2853:
+// Throws: Nothing unless an exception is thrown by the assignment operator or 
move assignment operator of T.
+{
+Throws arr[] = {1, 2, 3};
+std::vector v(arr, arr+3);
+Throws::sThrows = true;
+v.erase(v.begin(), --v.end());
+assert(v.size() == 1);
+v.erase(v.begin(), v.end());
+assert(v.size() == 0);
+}
 }

Modified: libcxx/trunk/www/cxx1z_status.html
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx1z_status.html?rev=300449=300448=300449=diff
==
--- libcxx/trunk/www/cxx1z_status.html (original)
+++ libcxx/trunk/www/cxx1z_status.html Mon Apr 17 08:19:14 2017
@@ -462,7 +462,7 @@
http://wg21.link/LWG2838;>2838is_literal_type specification 
needs a little cleanupKonaComplete
http://wg21.link/LWG2842;>2842in_place_t 
check for optional::optional(U) should decay 
UKonaComplete
http://wg21.link/LWG2850;>2850std::function move constructor 
does unnecessary workKona
-   http://wg21.link/LWG2853;>2853Possible 
inconsistency in specification of erase in 
[vector.modifiers]Kona
+   http://wg21.link/LWG2853;>2853Possible 
inconsistency in specification of erase in 
[vector.modifiers]KonaComplete
http://wg21.link/LWG2855;>2855std::throw_with_nested("string_literal")KonaComplete
http://wg21.link/LWG2857;>2857{variant,optional,any}::emplace
 should return the constructed valueKonaComplete
http://wg21.link/LWG2861;>2861basic_string should require 
that charT match traits::char_typeKonaComplete
@@ -489,7 +489,7 @@
 
   
 
-  Last Updated: 13-Apr-2017
+  Last Updated: 17-Apr-2017
 
 
 


___
cfe-commits mailing 

[PATCH] D32113: Add path from clang to doxygen document include header

2017-04-17 Thread Yuka Takahashi via Phabricator via cfe-commits
yamaguchi added inline comments.



Comment at: docs/doxygen.cfg.in:158
+STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang
+STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang-c
 

v.g.vassilev wrote:
> We should be stripping `@abs_srcdir@/../include` because in reality the way 
> the user will include those files is via `#include "clang/Sema/Sema.h" for 
> instance.
Do you mean we should be stripping 
```
@abs_srcdir@/../include
```
rather than

```
@abs_srcdir@/..
@abs_srcdir@/../include/clang
@abs_srcdir@/../include/clang-c
```
?


https://reviews.llvm.org/D32113



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


[PATCH] D32113: Add path from clang to doxygen document include header

2017-04-17 Thread Vassil Vassilev via Phabricator via cfe-commits
v.g.vassilev added inline comments.



Comment at: docs/doxygen.cfg.in:158
+STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang
+STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang-c
 

We should be stripping `@abs_srcdir@/../include` because in reality the way the 
user will include those files is via `#include "clang/Sema/Sema.h" for instance.


https://reviews.llvm.org/D32113



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


[PATCH] D32113: Add path from clang to doxygen document include header

2017-04-17 Thread Yuka Takahashi via Phabricator via cfe-commits
yamaguchi updated this revision to Diff 95434.
yamaguchi added a comment.

It worked, and this code generates #include "Sema/Sema.h".


https://reviews.llvm.org/D32113

Files:
  docs/doxygen.cfg.in


Index: docs/doxygen.cfg.in
===
--- docs/doxygen.cfg.in
+++ docs/doxygen.cfg.in
@@ -132,7 +132,7 @@
 # shortest path that makes the file name unique will be used
 # The default value is: YES.
 
-FULL_PATH_NAMES= NO
+FULL_PATH_NAMES= YES
 
 # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
 # Stripping is only done if one of the specified strings matches the left-hand
@@ -144,16 +144,18 @@
 # will be relative from the directory where doxygen is started.
 # This tag requires that the tag FULL_PATH_NAMES is set to YES.
 
-STRIP_FROM_PATH= ../..
+STRIP_FROM_PATH= @abs_srcdir@/..
 
 # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
 # path mentioned in the documentation of a class, which tells the reader which
 # header file to include in order to use a class. If left blank only the name 
of
 # the header file containing the class definition is used. Otherwise one should
 # specify the list of include paths that are normally passed to the compiler
 # using the -I flag.
 
-STRIP_FROM_INC_PATH=
+STRIP_FROM_INC_PATH= @abs_srcdir@/..
+STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang
+STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang-c
 
 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
 # less readable) file names. This can be useful is your file systems doesn't
@@ -513,7 +515,7 @@
 # files with double quotes in the documentation rather than with sharp 
brackets.
 # The default value is: NO.
 
-FORCE_LOCAL_INCLUDES   = NO
+FORCE_LOCAL_INCLUDES   = YES
 
 # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
 # documentation for inline members.


Index: docs/doxygen.cfg.in
===
--- docs/doxygen.cfg.in
+++ docs/doxygen.cfg.in
@@ -132,7 +132,7 @@
 # shortest path that makes the file name unique will be used
 # The default value is: YES.
 
-FULL_PATH_NAMES= NO
+FULL_PATH_NAMES= YES
 
 # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
 # Stripping is only done if one of the specified strings matches the left-hand
@@ -144,16 +144,18 @@
 # will be relative from the directory where doxygen is started.
 # This tag requires that the tag FULL_PATH_NAMES is set to YES.
 
-STRIP_FROM_PATH= ../..
+STRIP_FROM_PATH= @abs_srcdir@/..
 
 # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
 # path mentioned in the documentation of a class, which tells the reader which
 # header file to include in order to use a class. If left blank only the name of
 # the header file containing the class definition is used. Otherwise one should
 # specify the list of include paths that are normally passed to the compiler
 # using the -I flag.
 
-STRIP_FROM_INC_PATH=
+STRIP_FROM_INC_PATH= @abs_srcdir@/..
+STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang
+STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang-c
 
 # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
 # less readable) file names. This can be useful is your file systems doesn't
@@ -513,7 +515,7 @@
 # files with double quotes in the documentation rather than with sharp brackets.
 # The default value is: NO.
 
-FORCE_LOCAL_INCLUDES   = NO
+FORCE_LOCAL_INCLUDES   = YES
 
 # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
 # documentation for inline members.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D32113: Add path from clang to doxygen document include header

2017-04-17 Thread Raphael Isemann via Phabricator via cfe-commits
teemperor added a comment.

Woops, my bad, seems like I tested just before you fixed it.

Because I read in the documentation that we could also pass include paths here, 
we could also try something like this:

  STRIP_FROM_INC_PATH= @abs_srcdir@/..
  STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang
  STRIP_FROM_INC_PATH+= @abs_srcdir@/../include/clang-c

That way we have the actual compiler include paths in there and we probably get 
the fully working `#include`s one has to do for a certain class. Could you test 
that? Something like `#include "Sema/Sema.h"` for the `Sema` class would be 
IMHO the best solution.

Not sure what STRIP_FROM_PATH is doing, but I think we can leave it at it's 
current value?

Otherwise I think this review is ready to go.


https://reviews.llvm.org/D32113



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


[PATCH] D31540: Prefer non-friend to friend in in redeclaration chain

2017-04-17 Thread Phabricator via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL300443: Address http://bugs.llvm.org/pr30994 so that a 
non-friend can properly replaceā€¦ (authored by yrnkrn).

Changed prior to commit:
  https://reviews.llvm.org/D31540?vs=94961=95425#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D31540

Files:
  cfe/trunk/include/clang/AST/DeclBase.h
  cfe/trunk/lib/AST/Decl.cpp
  cfe/trunk/lib/AST/DeclBase.cpp
  cfe/trunk/test/SemaTemplate/friend-template.cpp

Index: cfe/trunk/include/clang/AST/DeclBase.h
===
--- cfe/trunk/include/clang/AST/DeclBase.h
+++ cfe/trunk/include/clang/AST/DeclBase.h
@@ -417,6 +417,8 @@
 return const_cast(this)->getTranslationUnitDecl();
   }
 
+  bool isThisDeclarationADefinition() const;
+
   bool isInAnonymousNamespace() const;
 
   bool isInStdNamespace() const;
Index: cfe/trunk/test/SemaTemplate/friend-template.cpp
===
--- cfe/trunk/test/SemaTemplate/friend-template.cpp
+++ cfe/trunk/test/SemaTemplate/friend-template.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
 // PR5057
 namespace test0 {
   namespace std {
@@ -68,17 +68,12 @@
   Foo foo;
 
   template struct X2a;
-
-  template struct X2b;
+  template struct X2b;// expected-note {{previous non-type template parameter with type 'int' is here}}
 
   template
   class X3 {
 template friend struct X2a;
-
-// FIXME: the redeclaration note ends up here because redeclaration
-// lookup ends up finding the friend target from X3.
-template friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \
-  // expected-note {{previous non-type template parameter with type 'int' is here}}
+template friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} 
   };
 
   X3 x3i; // okay
@@ -297,14 +292,11 @@
   int n = C::D().f();
 
   struct F {
-template struct G;
+template struct G; // expected-note {{previous}}
   };
   template struct H {
-// FIXME: As with cases above, the note here is on an unhelpful declaration,
-// and should point to the declaration of G within F.
 template friend struct F::G; // \
-  // expected-error {{different type 'char' in template redeclaration}} \
-  // expected-note {{previous}}
+  // expected-error {{different type 'char' in template redeclaration}}
   };
   H h1; // ok
   H h2; // expected-note {{instantiation}}
@@ -329,3 +321,11 @@
 foo(b); // expected-note {{in instantiation}}
   }
 }
+namespace PR30994 {
+  void f();
+  struct A {
+[[deprecated]] friend void f() {} // \
+  expected-note {{has been explicitly marked deprecated here}}
+  };
+  void g() { f(); } // expected-warning {{is deprecated}}
+}
Index: cfe/trunk/lib/AST/Decl.cpp
===
--- cfe/trunk/lib/AST/Decl.cpp
+++ cfe/trunk/lib/AST/Decl.cpp
@@ -1536,6 +1536,10 @@
   if (isa(this))
 return false;
 
+  if (getFriendObjectKind() > OldD->getFriendObjectKind() &&
+  !isThisDeclarationADefinition())
+return false;
+
   // For parameters, pick the newer one. This is either an error or (in
   // Objective-C) permitted as an extension.
   if (isa(this))
Index: cfe/trunk/lib/AST/DeclBase.cpp
===
--- cfe/trunk/lib/AST/DeclBase.cpp
+++ cfe/trunk/lib/AST/DeclBase.cpp
@@ -861,6 +861,21 @@
   return Ty->getAs();
 }
 
+bool Decl::isThisDeclarationADefinition() const {
+  if (auto *TD = dyn_cast(this))
+return TD->isThisDeclarationADefinition();
+  if (auto *FD = dyn_cast(this))
+return FD->isThisDeclarationADefinition();
+  if (auto *VD = dyn_cast(this))
+return VD->isThisDeclarationADefinition();
+  if (auto *CTD = dyn_cast(this))
+return CTD->isThisDeclarationADefinition();
+  if (auto *FTD = dyn_cast(this))
+return FTD->isThisDeclarationADefinition();
+  if (auto *VTD = dyn_cast(this))
+return VTD->isThisDeclarationADefinition();
+  return false;
+}
 
 /// Starting at a given context (a Decl or DeclContext), look for a
 /// code context that is not a closure (a lambda, block, etc.).
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r300443 - Address http://bugs.llvm.org/pr30994 so that a non-friend can properly replace a friend, and a visible friend can properly replace an invisible friend but not vice verse, and definitions are

2017-04-17 Thread Yaron Keren via cfe-commits
Author: yrnkrn
Date: Mon Apr 17 03:51:20 2017
New Revision: 300443

URL: http://llvm.org/viewvc/llvm-project?rev=300443=rev
Log:
Address http://bugs.llvm.org/pr30994 so that a non-friend can properly replace 
a friend, and a visible friend can properly replace an invisible friend but not 
vice verse, and definitions are not replaced. This fixes the two FIXME in 
SemaTemplate/friend-template.cpp.

The code implements Richard Smith suggestion in comment 3 of the PR.

reviewer: Vassil Vassilev

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


Modified:
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/test/SemaTemplate/friend-template.cpp

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=300443=300442=300443=diff
==
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Mon Apr 17 03:51:20 2017
@@ -417,6 +417,8 @@ public:
 return const_cast(this)->getTranslationUnitDecl();
   }
 
+  bool isThisDeclarationADefinition() const;
+
   bool isInAnonymousNamespace() const;
 
   bool isInStdNamespace() const;

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=300443=300442=300443=diff
==
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon Apr 17 03:51:20 2017
@@ -1536,6 +1536,10 @@ bool NamedDecl::declarationReplaces(Name
   if (isa(this))
 return false;
 
+  if (getFriendObjectKind() > OldD->getFriendObjectKind() &&
+  !isThisDeclarationADefinition())
+return false;
+
   // For parameters, pick the newer one. This is either an error or (in
   // Objective-C) permitted as an extension.
   if (isa(this))

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=300443=300442=300443=diff
==
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Mon Apr 17 03:51:20 2017
@@ -861,6 +861,21 @@ const FunctionType *Decl::getFunctionTyp
   return Ty->getAs();
 }
 
+bool Decl::isThisDeclarationADefinition() const {
+  if (auto *TD = dyn_cast(this))
+return TD->isThisDeclarationADefinition();
+  if (auto *FD = dyn_cast(this))
+return FD->isThisDeclarationADefinition();
+  if (auto *VD = dyn_cast(this))
+return VD->isThisDeclarationADefinition();
+  if (auto *CTD = dyn_cast(this))
+return CTD->isThisDeclarationADefinition();
+  if (auto *FTD = dyn_cast(this))
+return FTD->isThisDeclarationADefinition();
+  if (auto *VTD = dyn_cast(this))
+return VTD->isThisDeclarationADefinition();
+  return false;
+}
 
 /// Starting at a given context (a Decl or DeclContext), look for a
 /// code context that is not a closure (a lambda, block, etc.).

Modified: cfe/trunk/test/SemaTemplate/friend-template.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/friend-template.cpp?rev=300443=300442=300443=diff
==
--- cfe/trunk/test/SemaTemplate/friend-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/friend-template.cpp Mon Apr 17 03:51:20 2017
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
 // PR5057
 namespace test0 {
   namespace std {
@@ -68,17 +68,12 @@ namespace test3 {
   Foo foo;
 
   template struct X2a;
-
-  template struct X2b;
+  template struct X2b;// expected-note {{previous 
non-type template parameter with type 'int' is here}}
 
   template
   class X3 {
 template friend struct X2a;
-
-// FIXME: the redeclaration note ends up here because redeclaration
-// lookup ends up finding the friend target from X3.
-template friend struct X2b; // expected-error 
{{template non-type parameter has a different type 'long' in template 
redeclaration}} \
-  // expected-note {{previous non-type template parameter with type 'int' 
is here}}
+template friend struct X2b; // expected-error 
{{template non-type parameter has a different type 'long' in template 
redeclaration}} 
   };
 
   X3 x3i; // okay
@@ -297,14 +292,11 @@ namespace PR12585 {
   int n = C::D().f();
 
   struct F {
-template struct G;
+template struct G; // expected-note {{previous}}
   };
   template struct H {
-// FIXME: As with cases above, the note here is on an unhelpful 
declaration,
-// and should point to the declaration of G within F.
 template friend struct F::G; // \
-  // expected-error {{different type 'char' in template redeclaration}} \
-  // expected-note {{previous}}
+  // expected-error