Re: r303317 - The constant expression evaluator should examine function arguments for non-constexpr function calls unless the EvalInfo says to stop.

2017-05-30 Thread Nick Lewycky via cfe-commits

Joerg Sonnenberger wrote:

On Wed, May 17, 2017 at 11:56:55PM -, Nick Lewycky via cfe-commits wrote:

Author: nicholas
Date: Wed May 17 18:56:54 2017
New Revision: 303317

URL: http://llvm.org/viewvc/llvm-project?rev=303317&view=rev
Log:
The constant expression evaluator should examine function arguments for 
non-constexpr function calls unless the EvalInfo says to stop.


Crashes with -std=c++11 on:

enum SizeHint { MinimumSize, MaximumSize };
class QSizeF {
public:
   constexpr QSizeF();
   QSizeF m_fn1(QSizeF);
   double wd;
   double ht;
};
constexpr QSizeF::QSizeF() : wd(), ht() {}
class A {
   void m_fn2();
   QSizeF m_fn3(SizeHint, const QSizeF&  = QSizeF());
};
void A::m_fn2() { m_fn3(MinimumSize).m_fn1(m_fn3(MaximumSize)); }


Did you run this with assertions disabled? This looks like another 
testcase for PR33140, but it should hit an assertion first.


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


r305233 - Revert r303316, a change to ExprConstant to evaluate function arguments.

2017-06-12 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Mon Jun 12 16:15:44 2017
New Revision: 305233

URL: http://llvm.org/viewvc/llvm-project?rev=305233&view=rev
Log:
Revert r303316, a change to ExprConstant to evaluate function arguments.

The patch was itself correct but it uncovered other bugs which are going to be 
difficult to fix, per PR33140.

Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/Sema/integer-overflow.c

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=305233&r1=305232&r2=305233&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Jun 12 16:15:44 2017
@@ -4588,7 +4588,7 @@ public:
   }
 
   bool handleCallExpr(const CallExpr *E, APValue &Result,
-  const LValue *ResultSlot) {
+ const LValue *ResultSlot) {
 const Expr *Callee = E->getCallee()->IgnoreParens();
 QualType CalleeType = Callee->getType();
 
@@ -4597,23 +4597,6 @@ public:
 auto Args = llvm::makeArrayRef(E->getArgs(), E->getNumArgs());
 bool HasQualifier = false;
 
-struct EvaluateIgnoredRAII {
-public:
-  EvaluateIgnoredRAII(EvalInfo &Info, llvm::ArrayRef ToEval)
-  : Info(Info), ToEval(ToEval) {}
-  ~EvaluateIgnoredRAII() {
-if (Info.noteFailure()) {
-  for (auto E : ToEval)
-EvaluateIgnoredValue(Info, E);
-}
-  }
-  void cancel() { ToEval = {}; }
-  void drop_front() { ToEval = ToEval.drop_front(); }
-private:
-  EvalInfo &Info;
-  llvm::ArrayRef ToEval;
-} EvalArguments(Info, Args);
-
 // Extract function decl and 'this' pointer from the callee.
 if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) {
   const ValueDecl *Member = nullptr;
@@ -4663,12 +4646,10 @@ public:
 if (Args.empty())
   return Error(E);
 
-const Expr *FirstArg = Args[0];
-Args = Args.drop_front();
-EvalArguments.drop_front();
-if (!EvaluateObjectArgument(Info, FirstArg, ThisVal))
+if (!EvaluateObjectArgument(Info, Args[0], ThisVal))
   return false;
 This = &ThisVal;
+Args = Args.slice(1);
   } else if (MD && MD->isLambdaStaticInvoker()) {   
 // Map the static invoker for the lambda back to the call operator.
 // Conveniently, we don't have to slice out the 'this' argument (as is
@@ -4720,12 +4701,8 @@ public:
 const FunctionDecl *Definition = nullptr;
 Stmt *Body = FD->getBody(Definition);
 
-if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body))
-  return false;
-
-EvalArguments.cancel();
-
-if (!HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, 
Info,
+if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body) ||
+!HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, 
Info,
 Result, ResultSlot))
   return false;
 

Modified: cfe/trunk/test/Sema/integer-overflow.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=305233&r1=305232&r2=305233&view=diff
==
--- cfe/trunk/test/Sema/integer-overflow.c (original)
+++ cfe/trunk/test/Sema/integer-overflow.c Mon Jun 12 16:15:44 2017
@@ -151,14 +151,6 @@ uint64_t check_integer_overflows(int i)
   uint64_t *b;
   uint64_t b2 = b[4608 * 1024 * 1024] + 1;
 
-// expected-warning@+1 {{overflow in expression; result is 536870912 with type 
'int'}} 
-  f0(4608 * 1024 * 1024);
-  f0(4608ul * 1024 * 1024);
-// expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}} 
-  f1(4608 * 1024 * 1024, 4608 * 1024 * 1024);
-// expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}} 
-  f2(4608 * 1024 * 1024, 4608 * 1024 * 1024);
-
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}}
   int j1 = i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024);
 


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


r305239 - Revert r301742 which made ExprConstant checking apply to all full-exprs.

2017-06-12 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Mon Jun 12 16:59:18 2017
New Revision: 305239

URL: http://llvm.org/viewvc/llvm-project?rev=305239&view=rev
Log:
Revert r301742 which made ExprConstant checking apply to all full-exprs.

This patch also exposed pre-existing bugs in clang, see PR32864 and PR33140#c3 .

Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/distribute_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/parallel_for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/target_simd_aligned_messages.cpp

cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/target_teams_distribute_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/taskloop_simd_aligned_messages.cpp

cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/teams_distribute_simd_aligned_messages.cpp
cfe/trunk/test/Sema/integer-overflow.c

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=305239&r1=305238&r2=305239&view=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Mon Jun 12 16:59:18 2017
@@ -10273,6 +10273,7 @@ private:
   void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
   void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
   void CheckBoolLikeConversion(Expr *E, SourceLocation CC);
+  void CheckForIntOverflow(Expr *E);
   void CheckUnsequencedOperations(Expr *E);
 
   /// \brief Perform semantic checks on a completed expression. This will 
either

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=305239&r1=305238&r2=305239&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Jun 12 16:59:18 2017
@@ -6226,10 +6226,6 @@ bool RecordExprEvaluator::VisitInitListE
 // the initializer list.
 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy : Field->getType());
 const Expr *Init = HaveInit ? E->getInit(ElementNo++) : &VIE;
-if (Init->isValueDependent()) {
-  Success = false;
-  continue;
-}
 
 // Temporarily override This, in case there's a CXXDefaultInitExpr in here.
 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
@@ -9940,8 +9936,7 @@ static bool EvaluateAsRValue(EvalInfo &I
 }
 
 static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
- const ASTContext &Ctx, bool &IsConst,
- bool IsCheckingForOverflow) {
+ const ASTContext &Ctx, bool &IsConst) {
   // Fast-path evaluations of integer literals, since we sometimes see files
   // containing vast quantities of these.
   if (const IntegerLiteral *L = dyn_cast(Exp)) {
@@ -9962,7 +9957,7 @@ static bool FastEvaluateAsRValue(const E
   // performance problems. Only do so in C++11 for now.
   if (Exp->isRValue() && (Exp->getType()->isArrayType() ||
   Exp->getType()->isRecordType()) &&
-  !Ctx.getLangOpts().CPlusPlus11 && !IsCheckingForOverflow) {
+  !Ctx.getLangOpts().CPlusPlus11) {
 IsConst = false;
 return true;
   }
@@ -9977,7 +9972,7 @@ static bool FastEvaluateAsRValue(const E
 /// will be applied to the result.
 bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const {
   bool IsConst;
-  if (FastEvaluateAsRValue(this, Result, Ctx, IsConst, false))
+  if (FastEvaluateAsRValue(this, Result, Ctx, IsConst))
 return IsConst;
   
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
@@ -10102,7 +10097,7 @@ APSInt Expr::EvaluateKnownConstInt(const
 void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
   bool IsConst;
   EvalResult EvalResult;
-  if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst, true)) {
+  if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst)) {
 EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
 (void)::EvaluateAsRValue(Info, this, EvalResult.Val);
   }

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=305239&r1=305238&r2=305239&view=diff
==
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Mon Jun 12

r321665 - Suppress undefined-template warnings when the pattern is declared in a system header.

2018-01-02 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Tue Jan  2 11:10:12 2018
New Revision: 321665

URL: http://llvm.org/viewvc/llvm-project?rev=321665&view=rev
Log:
Suppress undefined-template warnings when the pattern is declared in a system 
header.

The way to fix an undefined-template warning is to add lines to the header file 
that defines the template pattern. We should suppress the warnings when the 
template pattern is in a system header because we don't expect users to edit 
those.

Modified:
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaTemplate/undefined-template.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=321665&r1=321664&r2=321665&view=diff
==
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Jan  2 11:10:12 2018
@@ -3812,7 +3812,8 @@ void Sema::InstantiateFunctionDefinition
   PendingInstantiations.push_back(
 std::make_pair(Function, PointOfInstantiation));
 } else if (TSK == TSK_ImplicitInstantiation) {
-  if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
+  if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
+  !getSourceManager().isInSystemHeader(PatternDecl->getLocStart())) {
 Diag(PointOfInstantiation, diag::warn_func_template_missing)
   << Function;
 Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);
@@ -4347,7 +4348,8 @@ void Sema::InstantiateVariableDefinition
 std::make_pair(Var, PointOfInstantiation));
 } else if (TSK == TSK_ImplicitInstantiation) {
   // Warn about missing definition at the end of translation unit.
-  if (AtEndOfTU && !getDiagnostics().hasErrorOccurred()) {
+  if (AtEndOfTU && !getDiagnostics().hasErrorOccurred() &&
+  !getSourceManager().isInSystemHeader(PatternDecl->getLocStart())) {
 Diag(PointOfInstantiation, diag::warn_var_template_missing)
   << Var;
 Diag(PatternDecl->getLocation(), diag::note_forward_template_decl);

Modified: cfe/trunk/test/SemaTemplate/undefined-template.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/undefined-template.cpp?rev=321665&r1=321664&r2=321665&view=diff
==
--- cfe/trunk/test/SemaTemplate/undefined-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/undefined-template.cpp Tue Jan  2 11:10:12 2018
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++14 -Wundefined-func-template 
%s
 
+#if !defined(INCLUDE)
 template  struct C1 {
   static char s_var_1;   // expected-note{{forward declaration of template 
entity is here}}
   static char s_var_2;   // expected-note{{forward declaration of template 
entity is here}}
@@ -142,6 +143,16 @@ namespace test_24 {
   void h(X x) { g(x); } // no warning for use of 'g' despite the 
declaration having been instantiated from a template
 }
 
+#define INCLUDE
+#include "undefined-template.cpp"
+void func_25(SystemHeader *x) {
+  x->meth();
+}
+
 int main() {
   return 0;
 }
+#else
+#pragma clang system_header
+template  struct SystemHeader { T meth(); };
+#endif


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


[clang-tools-extra] r359329 - Fix typo in documentation.

2019-04-26 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Fri Apr 26 10:56:22 2019
New Revision: 359329

URL: http://llvm.org/viewvc/llvm-project?rev=359329&view=rev
Log:
Fix typo in documentation.

Modified:
clang-tools-extra/trunk/docs/clang-tidy/checks/abseil-time-comparison.rst

Modified: 
clang-tools-extra/trunk/docs/clang-tidy/checks/abseil-time-comparison.rst
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/abseil-time-comparison.rst?rev=359329&r1=359328&r2=359329&view=diff
==
--- clang-tools-extra/trunk/docs/clang-tidy/checks/abseil-time-comparison.rst 
(original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/abseil-time-comparison.rst 
Fri Apr 26 10:56:22 2019
@@ -6,7 +6,7 @@ abseil-time-comparison
 Prefer comparisons in the ``absl::Time`` domain instead of the integer domain.
 
 N.B.: In cases where an ``absl::Time`` is being converted to an integer,
-alignment may occur. If the comparison depends on this alingment, doing the
+alignment may occur. If the comparison depends on this alignment, doing the
 comparison in the ``absl::Time`` domain may yield a different result. In
 practice this is very rare, and still indicates a bug which should be fixed.
 


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


Re: [PATCH] D24712: Replace 'isProvablyNonNull' with existing utility llvm::IsKnownNonNull.

2016-09-19 Thread Nick Lewycky via cfe-commits
On 19 September 2016 at 15:58, John McCall  wrote:

> rjmccall added a comment.
>
> Actually, that should demonstrate the difference, assuming the LLVM
> function looks through selects, since IRGen should generate that as a
> select.
>

It doesn't look past the Value* you hand it. As well as isa, it
returns true on Arguments marked nonnull, byval, inalloca or
dereferenceable, global variables in addrspace 0 and not extern_weak, load
instructions marked with !nonnull metadata, or a call/invoke with the
nonnull parameter attribute on the return. It doesn't look at operands.


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


r281979 - Replace 'isProvablyNonNull' with existing utility llvm::IsKnownNonNull which handles more cases. Noticed by inspection.

2016-09-20 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Tue Sep 20 10:49:58 2016
New Revision: 281979

URL: http://llvm.org/viewvc/llvm-project?rev=281979&view=rev
Log:
Replace 'isProvablyNonNull' with existing utility llvm::IsKnownNonNull which 
handles more cases. Noticed by inspection.

Because of how the IR generation works, this isn't expected to cause an 
observable difference.

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=281979&r1=281978&r2=281979&view=diff
==
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Tue Sep 20 10:49:58 2016
@@ -29,6 +29,7 @@
 #include "clang/CodeGen/SwiftCallingConv.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/StringExtras.h"
+#include "llvm/Analysis/ValueTracking.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/CallSite.h"
@@ -2905,10 +2906,6 @@ static bool isProvablyNull(llvm::Value *
   return isa(addr);
 }
 
-static bool isProvablyNonNull(llvm::Value *addr) {
-  return isa(addr);
-}
-
 /// Emit the actual writing-back of a writeback.
 static void emitWriteback(CodeGenFunction &CGF,
   const CallArgList::Writeback &writeback) {
@@ -2921,7 +2918,7 @@ static void emitWriteback(CodeGenFunctio
 
   // If the argument wasn't provably non-null, we need to null check
   // before doing the store.
-  bool provablyNonNull = isProvablyNonNull(srcAddr.getPointer());
+  bool provablyNonNull = llvm::isKnownNonNull(srcAddr.getPointer());
   if (!provablyNonNull) {
 llvm::BasicBlock *writebackBB = CGF.createBasicBlock("icr.writeback");
 contBB = CGF.createBasicBlock("icr.done");
@@ -3061,7 +3058,7 @@ static void emitWritebackArg(CodeGenFunc
   // If the address is *not* known to be non-null, we need to switch.
   llvm::Value *finalArgument;
 
-  bool provablyNonNull = isProvablyNonNull(srcAddr.getPointer());
+  bool provablyNonNull = llvm::isKnownNonNull(srcAddr.getPointer());
   if (provablyNonNull) {
 finalArgument = temp.getPointer();
   } else {


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


r281996 - Fix typo in documentation.

2016-09-20 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Tue Sep 20 13:37:25 2016
New Revision: 281996

URL: http://llvm.org/viewvc/llvm-project?rev=281996&view=rev
Log:
Fix typo in documentation.

Since this is a header it will break links to this section.

Modified:
cfe/trunk/docs/UndefinedBehaviorSanitizer.rst

Modified: cfe/trunk/docs/UndefinedBehaviorSanitizer.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/UndefinedBehaviorSanitizer.rst?rev=281996&r1=281995&r2=281996&view=diff
==
--- cfe/trunk/docs/UndefinedBehaviorSanitizer.rst (original)
+++ cfe/trunk/docs/UndefinedBehaviorSanitizer.rst Tue Sep 20 13:37:25 2016
@@ -66,8 +66,8 @@ pointer.
 
 .. _ubsan-checks:
 
-Availablle checks
-=
+Available checks
+
 
 Available checks are:
 


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


patch: clean up in EmitValueForIvarAtOffset

2016-10-09 Thread Nick Lewycky via cfe-commits
The attached patch makes the LValue created in EmitValueForIvarAtOffset
have the same Qualifiers in the LValue as the QualType in the LValue.
Noticed when auditing for reasons the QualType would different from the
Qualifiers in an LValue. No functionality change.

Please review!

Nick


lvalue-qualifiers-1.patch
Description: Binary data
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r283795 - Make the LValue created in EmitValueForIvarAtOffset have the same Qualifiers in the LValue as the QualType in the LValue. No functionality change intended.

2016-10-10 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Mon Oct 10 15:07:13 2016
New Revision: 283795

URL: http://llvm.org/viewvc/llvm-project?rev=283795&view=rev
Log:
Make the LValue created in EmitValueForIvarAtOffset have the same Qualifiers in 
the LValue as the QualType in the LValue. No functionality change intended.

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

Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp?rev=283795&r1=283794&r2=283795&view=diff
==
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.cpp Mon Oct 10 15:07:13 2016
@@ -90,7 +90,7 @@ LValue CGObjCRuntime::EmitValueForIvarAt
unsigned CVRQualifiers,
llvm::Value *Offset) {
   // Compute (type*) ( (char *) BaseValue + Offset)
-  QualType IvarTy = Ivar->getType();
+  QualType IvarTy = Ivar->getType().withCVRQualifiers(CVRQualifiers);
   llvm::Type *LTy = CGF.CGM.getTypes().ConvertTypeForMem(IvarTy);
   llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, CGF.Int8PtrTy);
   V = CGF.Builder.CreateInBoundsGEP(V, Offset, "add.ptr");
@@ -98,7 +98,6 @@ LValue CGObjCRuntime::EmitValueForIvarAt
   if (!Ivar->isBitField()) {
 V = CGF.Builder.CreateBitCast(V, llvm::PointerType::getUnqual(LTy));
 LValue LV = CGF.MakeNaturalAlignAddrLValue(V, IvarTy);
-LV.getQuals().addCVRQualifiers(CVRQualifiers);
 return LV;
   }
 
@@ -139,9 +138,7 @@ LValue CGObjCRuntime::EmitValueForIvarAt
   Addr = CGF.Builder.CreateElementBitCast(Addr,
llvm::Type::getIntNTy(CGF.getLLVMContext(),
  Info->StorageSize));
-  return LValue::MakeBitfield(Addr, *Info,
-  IvarTy.withCVRQualifiers(CVRQualifiers),
-  AlignmentSource::Decl);
+  return LValue::MakeBitfield(Addr, *Info, IvarTy, AlignmentSource::Decl);
 }
 
 namespace {


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


[PATCH] D23734: Add -fprofile-dir= to clang.

2016-08-19 Thread Nick Lewycky via cfe-commits
nlewycky created this revision.
nlewycky added subscribers: llvm-commits, cfe-commits.

-fprofile-dir=path allows the user to specify where .gcda files should be 
emitted when the program is run. In particular, this is the first flag that 
causes the .gcno and .o files to have different paths, LLVM is extended to 
support this. -fprofile-dir= does not change the file name in the .gcno (and 
thus where lcov looks for the source) but it does change the name in the .gcda 
(and thus where the runtime library writes the .gcda file). It's different from 
a GCOV_PREFIX because a user can observe that the GCOV_PREFIX_STRIP will strip 
paths off of -fprofile-dir= but not off of a supplied GCOV_PREFIX.

To implement this we split -coverage-file into -coverage-data-file and 
-coverage-notes-file to specify the two different names. The !llvm.gcov 
metadata node grows from a 2-element form {string coverage-file, node dbg.cu} 
to 3-elements, {string coverage-notes-file, string coverage-data-file, node 
dbg.cu}. In the 3-element form, the file name is already "mangled" with 
.gcno/.gcda suffixes, while the 2-element form left that to the middle end pass.

https://reviews.llvm.org/D23734

Files:
  lib/Transforms/Instrumentation/GCOVProfiling.cpp
  test/Transforms/GCOVProfiling/three-element-mdnode.ll

Index: test/Transforms/GCOVProfiling/three-element-mdnode.ll
===
--- test/Transforms/GCOVProfiling/three-element-mdnode.ll
+++ test/Transforms/GCOVProfiling/three-element-mdnode.ll
@@ -0,0 +1,27 @@
+; RUN: echo '!9 = !{!"%T/aaa.gcno", !"%T/bbb.gcda", !0}' > %t1
+; RUN: cat %s %t1 > %t2
+; RUN: opt -insert-gcov-profiling -S -o %t3 < %t2
+; RUN: grep _Z3foov %T/aaa.gcno
+; RUN: grep bbb.gcda %t3
+; RUN: rm %T/aaa.gcno
+
+define void @_Z3foov() !dbg !5 {
+entry:
+  ret void, !dbg !8
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!10}
+!llvm.gcov = !{!9}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 (trunk 177323)", isOptimized: false, emissionKind: FullDebug, file: !2, enums: !3, retainedTypes: !3, globals: !3, imports:  !3)
+!1 = !DIFile(filename: "hello.cc", directory: "/home/nlewycky")
+!2 = !DIFile(filename: "hello.cc", directory: "/home/nlewycky")
+!3 = !{}
+!5 = distinct !DISubprogram(name: "foo", linkageName: "_Z3foov", line: 1, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 1, file: !1, scope: !1, type: !6, variables: !3)
+!6 = !DISubroutineType(types: !7)
+!7 = !{null}
+!8 = !DILocation(line: 1, scope: !5)
+
+
+!10 = !{i32 1, !"Debug Info Version", i32 3}
Index: lib/Transforms/Instrumentation/GCOVProfiling.cpp
===
--- lib/Transforms/Instrumentation/GCOVProfiling.cpp
+++ lib/Transforms/Instrumentation/GCOVProfiling.cpp
@@ -118,7 +118,8 @@
   Function *insertFlush(ArrayRef>);
   void insertIndirectCounterIncrement();
 
-  std::string mangleName(const DICompileUnit *CU, const char *NewStem);
+  enum GCovFileType { GCNO, GCDA };
+  std::string mangleName(const DICompileUnit *CU, GCovFileType NewStem);
 
   GCOVOptions Options;
 
@@ -418,24 +419,37 @@
 }
 
 std::string GCOVProfiler::mangleName(const DICompileUnit *CU,
- const char *NewStem) {
+ GCovFileType NewStem) {
   if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) {
 for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) {
   MDNode *N = GCov->getOperand(i);
+  if (N->getNumOperands() == 3) {
+// These nodes have no mangling to apply, it's stored mangled in the
+// bitcode.
+MDString *NotesFile = dyn_cast(N->getOperand(0));
+MDString *DataFile = dyn_cast(N->getOperand(1));
+MDNode *CompileUnit = dyn_cast(N->getOperand(2));
+if (!NotesFile || !DataFile || !CompileUnit) continue;
+if (CompileUnit == CU)
+  return NewStem == GCNO ? NotesFile->getString()
+ : DataFile->getString();
+  }
   if (N->getNumOperands() != 2) continue;
   MDString *GCovFile = dyn_cast(N->getOperand(0));
   MDNode *CompileUnit = dyn_cast(N->getOperand(1));
   if (!GCovFile || !CompileUnit) continue;
   if (CompileUnit == CU) {
-SmallString<128> Filename = GCovFile->getString();
-sys::path::replace_extension(Filename, NewStem);
+SmallString<128> Filename;
+Filename = GCovFile->getString();
+sys::path::replace_extension(Filename,
+ NewStem == GCNO ? "gcno" : "gcda");
 return Filename.str();
   }
 }
   }
 
   SmallString<128> Filename = CU->getFilename();
-  sys::path::replace_extension(Filename, NewStem);
+  sys::path::replace_extension(Filename, NewStem == GCNO ? "gcno" : "gcda");
   StringRef FName = sys::path::filename(Filename);
   SmallString<128> 

Re: [PATCH] D23734: Add -fprofile-dir= to clang.

2016-08-19 Thread Nick Lewycky via cfe-commits
nlewycky updated this revision to Diff 68755.
nlewycky added a comment.

Forgot clang changes!


https://reviews.llvm.org/D23734

Files:
  lib/Transforms/Instrumentation/GCOVProfiling.cpp
  test/Transforms/GCOVProfiling/three-element-mdnode.ll
  tools/clang/include/clang/Driver/CC1Options.td
  tools/clang/include/clang/Driver/Options.td
  tools/clang/include/clang/Frontend/CodeGenOptions.h
  tools/clang/lib/CodeGen/CodeGenModule.cpp
  tools/clang/lib/Driver/Tools.cpp
  tools/clang/lib/Frontend/CompilerInvocation.cpp
  tools/clang/test/CodeGen/code-coverage.c
  tools/clang/test/Driver/clang_f_opts.c
  tools/clang/test/Driver/coverage_no_integrated_as.c

Index: tools/clang/test/Driver/coverage_no_integrated_as.c
===
--- tools/clang/test/Driver/coverage_no_integrated_as.c
+++ tools/clang/test/Driver/coverage_no_integrated_as.c
@@ -17,7 +17,7 @@
 // RUN: %clang -### -c -fprofile-arcs -no-integrated-as %s -o foo/bar.o 2>&1 | FileCheck -check-prefix=CHECK-GCNO-LOCATION-REL-PATH %s
 
 
-// CHECK-GCNO-DEFAULT-LOCATION: "-coverage-file" "{{.*}}{{/|}}coverage_no_integrated_as.c"
-// CHECK-GCNO-DEFAULT-LOCATION-NOT: "-coverage-file" "/tmp/{{.*}}/coverage_no_integrated_as.c"
-// CHECK-GCNO-LOCATION: "-coverage-file" "{{.*}}/foo/bar.o"
-// CHECK-GCNO-LOCATION-REL-PATH: "-coverage-file" "{{.*}}{{/|}}foo/bar.o"
+// CHECK-GCNO-DEFAULT-LOCATION: "-coverage-notes-file" "{{.*}}{{/|}}coverage_no_integrated_as.c"
+// CHECK-GCNO-DEFAULT-LOCATION-NOT: "-coverage-notes-file" "/tmp/{{.*}}/coverage_no_integrated_as.c"
+// CHECK-GCNO-LOCATION: "-coverage-notes-file" "{{.*}}/foo/bar.gcno"
+// CHECK-GCNO-LOCATION-REL-PATH: "-coverage-notes-file" "{{.*}}{{/|}}foo/bar.gcno"
Index: tools/clang/test/Driver/clang_f_opts.c
===
--- tools/clang/test/Driver/clang_f_opts.c
+++ tools/clang/test/Driver/clang_f_opts.c
@@ -66,6 +66,16 @@
 // CHECK-PROFILE-ARCS: "-femit-coverage-data"
 // CHECK-NO-PROFILE-ARCS-NOT: "-femit-coverage-data"
 
+// RUN: %clang -### -S -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-UNUSED %s
+// RUN: %clang -### -S -ftest-coverage -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-UNUSED %s
+// RUN: %clang -### -S -fprofile-arcs -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR %s
+// RUN: %clang -### -S --coverage -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR %s
+// RUN: %clang -### -S -fprofile-arcs -fno-profile-arcs -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-NEITHER %s
+// CHECK-PROFILE-DIR: "-coverage-data-file" "abc
+// CHECK-PROFILE-DIR-UNUSED: argument unused
+// CHECK-PROFILE-DIR-UNUSED-NOT: "-coverage-data-file" "abc
+// CHECK-PROFILE-DIR-NEITHER-NOT: argument unused
+
 // RUN: %clang -### -S -fprofile-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-LLVM %s
 // RUN: %clang -### -S -fprofile-instr-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE %s
 // RUN: %clang -### -S -fprofile-generate=/some/dir %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-DIR %s
@@ -212,7 +222,6 @@
 // RUN: -fdefer-pop -fno-defer-pop\
 // RUN: -fprefetch-loop-arrays -fno-prefetch-loop-arrays  \
 // RUN: -fprofile-correction -fno-profile-correction  \
-// RUN: -fprofile-dir=bar \
 // RUN: -fprofile-values -fno-profile-values  \
 // RUN: -frounding-math -fno-rounding-math\
 // RUN: -fsee -fno-see\
@@ -290,7 +299,6 @@
 // RUN: -fkeep-inline-functions   \
 // RUN: -fno-keep-inline-functions\
 // RUN: -freorder-blocks  \
-// RUN: -fprofile-dir=/rand/dir   \
 // RUN: -falign-functions \
 // RUN: -falign-functions=1   \
 // RUN: -ffloat-store \
@@ -357,7 +365,6 @@
 // CHECK-WARNING-DAG: optimization flag '-fkeep-inline-functions' is not supported
 // CHECK-WARNING-DAG: optimization flag '-fno-keep-inline-functions' is not supported
 // CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported
-// CHECK-WARNING-DAG: optimization flag '-fprofile-dir=/rand/dir' is not supported
 // CHECK-WARNING-DAG: optimization flag '-falign-functions' is not supported
 // CHECK-WARNING-DAG: optimization flag '-falign-functions=1' is not supported
 // CHECK-WARNING-DAG: optimization flag '-ffloat-store' is not supported
Index: tools/clang/test/CodeGen/code-cove

Re: [PATCH] D23734: Add -fprofile-dir= to clang.

2016-08-29 Thread Nick Lewycky via cfe-commits
nlewycky added a comment.

Ping!

I think the review this patch really needs is a comparison to GCC's 
implementation to double-check that it really does the same thing that GCC 
does. Is there a gcov user who could take a look at this?


https://reviews.llvm.org/D23734



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


Re: [PATCH] D23734: Add -fprofile-dir= to clang.

2016-08-30 Thread Nick Lewycky via cfe-commits
nlewycky updated this revision to Diff 69778.
nlewycky marked 5 inline comments as done.

https://reviews.llvm.org/D23734

Files:
  lib/Transforms/Instrumentation/GCOVProfiling.cpp
  test/Transforms/GCOVProfiling/three-element-mdnode.ll
  tools/clang/include/clang/Driver/CC1Options.td
  tools/clang/include/clang/Driver/Options.td
  tools/clang/include/clang/Frontend/CodeGenOptions.h
  tools/clang/lib/CodeGen/CodeGenModule.cpp
  tools/clang/lib/Driver/Tools.cpp
  tools/clang/lib/Frontend/CompilerInvocation.cpp
  tools/clang/test/CodeGen/code-coverage.c
  tools/clang/test/Driver/clang_f_opts.c
  tools/clang/test/Driver/coverage_no_integrated_as.c

Index: tools/clang/test/Driver/coverage_no_integrated_as.c
===
--- tools/clang/test/Driver/coverage_no_integrated_as.c
+++ tools/clang/test/Driver/coverage_no_integrated_as.c
@@ -17,7 +17,7 @@
 // RUN: %clang -### -c -fprofile-arcs -no-integrated-as %s -o foo/bar.o 2>&1 | FileCheck -check-prefix=CHECK-GCNO-LOCATION-REL-PATH %s
 
 
-// CHECK-GCNO-DEFAULT-LOCATION: "-coverage-file" "{{.*}}{{/|}}coverage_no_integrated_as.c"
-// CHECK-GCNO-DEFAULT-LOCATION-NOT: "-coverage-file" "/tmp/{{.*}}/coverage_no_integrated_as.c"
-// CHECK-GCNO-LOCATION: "-coverage-file" "{{.*}}/foo/bar.o"
-// CHECK-GCNO-LOCATION-REL-PATH: "-coverage-file" "{{.*}}{{/|}}foo/bar.o"
+// CHECK-GCNO-DEFAULT-LOCATION: "-coverage-notes-file" "{{.*}}{{/|}}coverage_no_integrated_as.c"
+// CHECK-GCNO-DEFAULT-LOCATION-NOT: "-coverage-notes-file" "/tmp/{{.*}}/coverage_no_integrated_as.c"
+// CHECK-GCNO-LOCATION: "-coverage-notes-file" "{{.*}}/foo/bar.gcno"
+// CHECK-GCNO-LOCATION-REL-PATH: "-coverage-notes-file" "{{.*}}{{/|}}foo/bar.gcno"
Index: tools/clang/test/Driver/clang_f_opts.c
===
--- tools/clang/test/Driver/clang_f_opts.c
+++ tools/clang/test/Driver/clang_f_opts.c
@@ -66,6 +66,16 @@
 // CHECK-PROFILE-ARCS: "-femit-coverage-data"
 // CHECK-NO-PROFILE-ARCS-NOT: "-femit-coverage-data"
 
+// RUN: %clang -### -S -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-UNUSED %s
+// RUN: %clang -### -S -ftest-coverage -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-UNUSED %s
+// RUN: %clang -### -S -fprofile-arcs -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR %s
+// RUN: %clang -### -S --coverage -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR %s
+// RUN: %clang -### -S -fprofile-arcs -fno-profile-arcs -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-NEITHER %s
+// CHECK-PROFILE-DIR: "-coverage-data-file" "abc
+// CHECK-PROFILE-DIR-UNUSED: argument unused
+// CHECK-PROFILE-DIR-UNUSED-NOT: "-coverage-data-file" "abc
+// CHECK-PROFILE-DIR-NEITHER-NOT: argument unused
+
 // RUN: %clang -### -S -fprofile-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-LLVM %s
 // RUN: %clang -### -S -fprofile-instr-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE %s
 // RUN: %clang -### -S -fprofile-generate=/some/dir %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-DIR %s
@@ -212,7 +222,6 @@
 // RUN: -fdefer-pop -fno-defer-pop\
 // RUN: -fprefetch-loop-arrays -fno-prefetch-loop-arrays  \
 // RUN: -fprofile-correction -fno-profile-correction  \
-// RUN: -fprofile-dir=bar \
 // RUN: -fprofile-values -fno-profile-values  \
 // RUN: -frounding-math -fno-rounding-math\
 // RUN: -fsee -fno-see\
@@ -290,7 +299,6 @@
 // RUN: -fkeep-inline-functions   \
 // RUN: -fno-keep-inline-functions\
 // RUN: -freorder-blocks  \
-// RUN: -fprofile-dir=/rand/dir   \
 // RUN: -falign-functions \
 // RUN: -falign-functions=1   \
 // RUN: -ffloat-store \
@@ -357,7 +365,6 @@
 // CHECK-WARNING-DAG: optimization flag '-fkeep-inline-functions' is not supported
 // CHECK-WARNING-DAG: optimization flag '-fno-keep-inline-functions' is not supported
 // CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported
-// CHECK-WARNING-DAG: optimization flag '-fprofile-dir=/rand/dir' is not supported
 // CHECK-WARNING-DAG: optimization flag '-falign-functions' is not supported
 // CHECK-WARNING-DAG: optimization flag '-falign-functions=1' is not supported
 // CHECK-WARNING-DAG: optimization flag '-ffloat-store' is not supported
Index: tools/clang/test/CodeGen/code-coverage.c

Re: [PATCH] D23734: Add -fprofile-dir= to clang.

2016-08-30 Thread Nick Lewycky via cfe-commits
nlewycky added inline comments.


Comment at: lib/Transforms/Instrumentation/GCOVProfiling.cpp:447
@@ -432,3 +446,3 @@
 return Filename.str();
   }
 }

compnerd wrote:
> It really feels like these two cases can be collapsed.
I don't see a great way to do that, so I picked the one which minimizes the 
cost of the common case. Having an !llvm.gcov node but no CU for the specific 
.o is uncommon: to get here you're building a program with some .bc's built 
with a frontend that emits an !llvm.gcov and some .bc's without, and then you 
llvm-linked them and are running the insert-gcov-profiling pass afterwards. 
Also, I assume that copying SmallString<128>'s around is slow, while looking up 
Value*'s is faster.

If you have a specific idea, I'm happy to try it. I'm not thrilled with the way 
it's written now.


Comment at: test/Transforms/GCOVProfiling/three-element-mdnode.ll:27
@@ +26,2 @@
+
+!10 = !{i32 1, !"Debug Info Version", i32 3}

The way this test was written, !10 would be parsed before !9. Swizzled it 
around to make !9 the !llvm.module.flags and !10 the !llvm.gcov node.


https://reviews.llvm.org/D23734



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


Re: [PATCH] D23734: Add -fprofile-dir= to clang.

2016-08-31 Thread Nick Lewycky via cfe-commits
nlewycky updated this revision to Diff 69905.

https://reviews.llvm.org/D23734

Files:
  lib/Transforms/Instrumentation/GCOVProfiling.cpp
  test/Transforms/GCOVProfiling/three-element-mdnode.ll
  tools/clang/include/clang/Driver/CC1Options.td
  tools/clang/include/clang/Driver/Options.td
  tools/clang/include/clang/Frontend/CodeGenOptions.h
  tools/clang/lib/CodeGen/CodeGenModule.cpp
  tools/clang/lib/Driver/Tools.cpp
  tools/clang/lib/Frontend/CompilerInvocation.cpp
  tools/clang/test/CodeGen/code-coverage.c
  tools/clang/test/Driver/clang_f_opts.c
  tools/clang/test/Driver/coverage_no_integrated_as.c

Index: tools/clang/test/Driver/coverage_no_integrated_as.c
===
--- tools/clang/test/Driver/coverage_no_integrated_as.c
+++ tools/clang/test/Driver/coverage_no_integrated_as.c
@@ -17,7 +17,7 @@
 // RUN: %clang -### -c -fprofile-arcs -no-integrated-as %s -o foo/bar.o 2>&1 | FileCheck -check-prefix=CHECK-GCNO-LOCATION-REL-PATH %s
 
 
-// CHECK-GCNO-DEFAULT-LOCATION: "-coverage-file" "{{.*}}{{/|}}coverage_no_integrated_as.c"
-// CHECK-GCNO-DEFAULT-LOCATION-NOT: "-coverage-file" "/tmp/{{.*}}/coverage_no_integrated_as.c"
-// CHECK-GCNO-LOCATION: "-coverage-file" "{{.*}}/foo/bar.o"
-// CHECK-GCNO-LOCATION-REL-PATH: "-coverage-file" "{{.*}}{{/|}}foo/bar.o"
+// CHECK-GCNO-DEFAULT-LOCATION: "-coverage-notes-file" "{{.*}}{{/|}}coverage_no_integrated_as.c"
+// CHECK-GCNO-DEFAULT-LOCATION-NOT: "-coverage-notes-file" "/tmp/{{.*}}/coverage_no_integrated_as.c"
+// CHECK-GCNO-LOCATION: "-coverage-notes-file" "{{.*}}/foo/bar.gcno"
+// CHECK-GCNO-LOCATION-REL-PATH: "-coverage-notes-file" "{{.*}}{{/|}}foo/bar.gcno"
Index: tools/clang/test/Driver/clang_f_opts.c
===
--- tools/clang/test/Driver/clang_f_opts.c
+++ tools/clang/test/Driver/clang_f_opts.c
@@ -66,6 +66,16 @@
 // CHECK-PROFILE-ARCS: "-femit-coverage-data"
 // CHECK-NO-PROFILE-ARCS-NOT: "-femit-coverage-data"
 
+// RUN: %clang -### -S -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-UNUSED %s
+// RUN: %clang -### -S -ftest-coverage -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-UNUSED %s
+// RUN: %clang -### -S -fprofile-arcs -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR %s
+// RUN: %clang -### -S --coverage -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR %s
+// RUN: %clang -### -S -fprofile-arcs -fno-profile-arcs -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-NEITHER %s
+// CHECK-PROFILE-DIR: "-coverage-data-file" "abc
+// CHECK-PROFILE-DIR-UNUSED: argument unused
+// CHECK-PROFILE-DIR-UNUSED-NOT: "-coverage-data-file" "abc
+// CHECK-PROFILE-DIR-NEITHER-NOT: argument unused
+
 // RUN: %clang -### -S -fprofile-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-LLVM %s
 // RUN: %clang -### -S -fprofile-instr-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE %s
 // RUN: %clang -### -S -fprofile-generate=/some/dir %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-DIR %s
@@ -212,7 +222,6 @@
 // RUN: -fdefer-pop -fno-defer-pop\
 // RUN: -fprefetch-loop-arrays -fno-prefetch-loop-arrays  \
 // RUN: -fprofile-correction -fno-profile-correction  \
-// RUN: -fprofile-dir=bar \
 // RUN: -fprofile-values -fno-profile-values  \
 // RUN: -frounding-math -fno-rounding-math\
 // RUN: -fsee -fno-see\
@@ -290,7 +299,6 @@
 // RUN: -fkeep-inline-functions   \
 // RUN: -fno-keep-inline-functions\
 // RUN: -freorder-blocks  \
-// RUN: -fprofile-dir=/rand/dir   \
 // RUN: -falign-functions \
 // RUN: -falign-functions=1   \
 // RUN: -ffloat-store \
@@ -357,7 +365,6 @@
 // CHECK-WARNING-DAG: optimization flag '-fkeep-inline-functions' is not supported
 // CHECK-WARNING-DAG: optimization flag '-fno-keep-inline-functions' is not supported
 // CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported
-// CHECK-WARNING-DAG: optimization flag '-fprofile-dir=/rand/dir' is not supported
 // CHECK-WARNING-DAG: optimization flag '-falign-functions' is not supported
 // CHECK-WARNING-DAG: optimization flag '-falign-functions=1' is not supported
 // CHECK-WARNING-DAG: optimization flag '-ffloat-store' is not supported
Index: tools/clang/test/CodeGen/code-coverage.c
===

r280306 - Add -fprofile-dir= to clang.

2016-08-31 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Wed Aug 31 18:04:32 2016
New Revision: 280306

URL: http://llvm.org/viewvc/llvm-project?rev=280306&view=rev
Log:
Add -fprofile-dir= to clang.

-fprofile-dir=path allows the user to specify where .gcda files should be
emitted when the program is run. In particular, this is the first flag that
causes the .gcno and .o files to have different paths, LLVM is extended to
support this. -fprofile-dir= does not change the file name in the .gcno (and
thus where lcov looks for the source) but it does change the name in the .gcda
(and thus where the runtime library writes the .gcda file). It's different from
a GCOV_PREFIX because a user can observe that the GCOV_PREFIX_STRIP will strip
paths off of -fprofile-dir= but not off of a supplied GCOV_PREFIX.

To implement this we split -coverage-file into -coverage-data-file and
-coverage-notes-file to specify the two different names. The !llvm.gcov
metadata node grows from a 2-element form {string coverage-file, node dbg.cu}
to 3-elements, {string coverage-notes-file, string coverage-data-file, node
dbg.cu}. In the 3-element form, the file name is already "mangled" with
.gcno/.gcda suffixes, while the 2-element form left that to the middle end
pass.

Modified:
cfe/trunk/include/clang/Driver/CC1Options.td
cfe/trunk/include/clang/Driver/Options.td
cfe/trunk/include/clang/Frontend/CodeGenOptions.h
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/Driver/Tools.cpp
cfe/trunk/lib/Frontend/CompilerInvocation.cpp
cfe/trunk/test/CodeGen/code-coverage.c
cfe/trunk/test/Driver/clang_f_opts.c
cfe/trunk/test/Driver/coverage_no_integrated_as.c

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=280306&r1=280305&r2=280306&view=diff
==
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Aug 31 18:04:32 2016
@@ -192,9 +192,14 @@ def femit_coverage_notes : Flag<["-"], "
   HelpText<"Emit a gcov coverage notes file when compiling.">;
 def femit_coverage_data: Flag<["-"], "femit-coverage-data">,
   HelpText<"Instrument the program to emit gcov coverage data when run.">;
-def coverage_file : Separate<["-"], "coverage-file">,
-  HelpText<"Emit coverage data to this filename. The extension will be 
replaced.">;
-def coverage_file_EQ : Joined<["-"], "coverage-file=">, Alias;
+def coverage_data_file : Separate<["-"], "coverage-data-file">,
+  HelpText<"Emit coverage data to this filename.">;
+def coverage_data_file_EQ : Joined<["-"], "coverage-data-file=">,
+  Alias;
+def coverage_notes_file : Separate<["-"], "coverage-notes-file">,
+  HelpText<"Emit coverage notes to this filename.">;
+def coverage_notes_file_EQ : Joined<["-"], "coverage-notes-file=">,
+  Alias;
 def coverage_cfg_checksum : Flag<["-"], "coverage-cfg-checksum">,
   HelpText<"Emit CFG checksum for functions in .gcno files.">;
 def coverage_no_function_names_in_data : Flag<["-"], 
"coverage-no-function-names-in-data">,

Modified: cfe/trunk/include/clang/Driver/Options.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=280306&r1=280305&r2=280306&view=diff
==
--- cfe/trunk/include/clang/Driver/Options.td (original)
+++ cfe/trunk/include/clang/Driver/Options.td Wed Aug 31 18:04:32 2016
@@ -2117,7 +2117,7 @@ multiclass BooleanFFlag {
 
 defm : BooleanFFlag<"keep-inline-functions">, 
Group;
 
-def fprofile_dir : Joined<["-"], "fprofile-dir=">, 
Group;
+def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group;
 
 def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group;
 

Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.h?rev=280306&r1=280305&r2=280306&view=diff
==
--- cfe/trunk/include/clang/Frontend/CodeGenOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/CodeGenOptions.h Wed Aug 31 18:04:32 2016
@@ -99,9 +99,13 @@ public:
   /// The code model to use (-mcmodel).
   std::string CodeModel;
 
-  /// The filename with path we use for coverage files. The extension will be
-  /// replaced.
-  std::string CoverageFile;
+  /// The filename with path we use for coverage data files. The runtime
+  /// allows further manipulation with the GCOV_PREFIX and GCOV_PREFIX_STRIP
+  /// environment variables.
+  std::string CoverageDataFile;
+
+  /// The filename with path we use for coverage notes files.
+  std::string CoverageNotesFile;
 
   /// The version string to put into coverage files.
   char CoverageVersion[4];

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=280306&r1=280305&r2=28

Re: [PATCH] D16171: Warning on redeclaring with a conflicting asm label

2016-09-12 Thread Nick Lewycky via cfe-commits
On 11 September 2016 at 21:14, Sam Shepperd via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> phabricss added a subscriber: phabricss.
> phabricss added a comment.
>
> It is still impossible to compile glibc with clang due to this bug.  Could
> this patch be reviewed please.
>

Firstly, I thought glibc had applied a patch to fix this bug? As in, the
error is correct and glibc fixed their bug?

As for the patch, its goal is to only demote an error to warning when the
function with conflicting asm labels is never used. That's pretty clearly a
workaround (if you ever call acoshl, then you'll get an error), but
moreover the check is implemented incorrectly. "New->isUsed()" will be
performed at the moment the new declaration is being parsed; of course it
hasn't been used yet. isUsed() will turn true only after it's used, after
we actually parse the rest of the code and build AST for the uses of the
new declaration. As I suggested in my last review comment, you would need
to defer the check until ActOnEndOfTranslationUnit in order to correctly
answer New->isUsed().

Or just not try to implement this workaround, and instead change how
codegen works so that we emit calls to functions with the same asm label
that gcc would choose.

https://reviews.llvm.org/D16171
>
>
>
> ___
> 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


r295006 - When the new expr's array size is an ICE, emit it as a constant expression.

2017-02-13 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Mon Feb 13 17:49:55 2017
New Revision: 295006

URL: http://llvm.org/viewvc/llvm-project?rev=295006&view=rev
Log:
When the new expr's array size is an ICE, emit it as a constant expression.

This bypasses integer sanitization checks which are redundant on the expression 
since it's been checked by Sema. Fixes a clang codegen assertion on "void 
test() { new int[0+1]{0}; }" when building with 
-fsanitize=signed-integer-overflow.

Modified:
cfe/trunk/lib/CodeGen/CGExprCXX.cpp
cfe/trunk/test/CodeGenCXX/new-array-init.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=295006&r1=295005&r2=295006&view=diff
==
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Mon Feb 13 17:49:55 2017
@@ -659,7 +659,10 @@ static llvm::Value *EmitCXXNewAllocSize(
   // Emit the array size expression.
   // We multiply the size of all dimensions for NumElements.
   // e.g for 'int[2][3]', ElemType is 'int' and NumElements is 6.
-  numElements = CGF.EmitScalarExpr(e->getArraySize());
+  numElements = CGF.CGM.EmitConstantExpr(e->getArraySize(),
+ CGF.getContext().getSizeType(), &CGF);
+  if (!numElements)
+numElements = CGF.EmitScalarExpr(e->getArraySize());
   assert(isa(numElements->getType()));
 
   // The number of elements can be have an arbitrary integer type;

Modified: cfe/trunk/test/CodeGenCXX/new-array-init.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/new-array-init.cpp?rev=295006&r1=295005&r2=295006&view=diff
==
--- cfe/trunk/test/CodeGenCXX/new-array-init.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/new-array-init.cpp Mon Feb 13 17:49:55 2017
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm -o - 
| FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm 
-fsanitize=signed-integer-overflow -o - | FileCheck --check-prefix=SIO %s
 
 // CHECK: @[[ABC4:.*]] = {{.*}} constant [4 x i8] c"abc\00"
 // CHECK: @[[ABC15:.*]] = {{.*}} constant [15 x i8] c"abc\00\00\00\00
@@ -116,3 +117,9 @@ void aggr_sufficient(int n) {
   struct Aggr { int a, b; };
   new Aggr[n] { 1, 2, 3 };
 }
+
+// SIO-LABEL: define void @_Z14constexpr_testv
+void constexpr_test() {
+  // SIO: call i8* @_Zna{{.}}(i32 4)
+  new int[0+1]{0};
+}


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


r301138 - Fix typo in comment.

2017-04-23 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Sun Apr 23 15:46:58 2017
New Revision: 301138

URL: http://llvm.org/viewvc/llvm-project?rev=301138&view=rev
Log:
Fix typo in comment.

Modified:
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=301138&r1=301137&r2=301138&view=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Sun Apr 23 15:46:58 2017
@@ -1406,7 +1406,7 @@ const internal::VariadicDynCastAllOfMatc
 ///
 /// Example: Given
 /// \code
-///   struct T {void func()};
+///   struct T {void func();};
 ///   T f();
 ///   void g(T);
 /// \endcode


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


r301520 - In the expression evaluator, descend into both the true and false expressions of a ConditionalOperator when the condition can't be evaluated and we're in an evaluation mode that says we shou

2017-04-27 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Thu Apr 27 02:11:09 2017
New Revision: 301520

URL: http://llvm.org/viewvc/llvm-project?rev=301520&view=rev
Log:
In the expression evaluator, descend into both the true and false expressions 
of a ConditionalOperator when the condition can't be evaluated and we're in an 
evaluation mode that says we should continue evaluating.

Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/Sema/integer-overflow.c

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=301520&r1=301519&r2=301520&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Apr 27 02:11:09 2017
@@ -4418,8 +4418,14 @@ private:
   bool HandleConditionalOperator(const ConditionalOperator *E) {
 bool BoolResult;
 if (!EvaluateAsBooleanCondition(E->getCond(), BoolResult, Info)) {
-  if (Info.checkingPotentialConstantExpression() && Info.noteFailure())
+  if (Info.checkingPotentialConstantExpression() && Info.noteFailure()) {
 CheckPotentialConstantConditional(E);
+return false;
+  }
+  if (Info.noteFailure()) {
+StmtVisitorTy::Visit(E->getTrueExpr());
+StmtVisitorTy::Visit(E->getFalseExpr());
+  }
   return false;
 }
 

Modified: cfe/trunk/test/Sema/integer-overflow.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=301520&r1=301519&r2=301520&view=diff
==
--- cfe/trunk/test/Sema/integer-overflow.c (original)
+++ cfe/trunk/test/Sema/integer-overflow.c Thu Apr 27 02:11:09 2017
@@ -148,6 +148,9 @@ uint64_t check_integer_overflows(int i)
   a[4608 * 1024 * 1024] = 1i;
 
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}}
+  (void)((i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024)) + 1);
+
+// expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}}
   return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));
 }
 


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


r301522 - In the expression evaluator, visit the index of an ArraySubscriptExpr even if we can't evaluate the base, if the evaluation mode tells us to continue evaluation.

2017-04-27 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Thu Apr 27 02:27:36 2017
New Revision: 301522

URL: http://llvm.org/viewvc/llvm-project?rev=301522&view=rev
Log:
In the expression evaluator, visit the index of an ArraySubscriptExpr even if 
we can't evaluate the base, if the evaluation mode tells us to continue 
evaluation.

Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/Sema/integer-overflow.c

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=301522&r1=301521&r2=301522&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Thu Apr 27 02:27:36 2017
@@ -5246,14 +5246,19 @@ bool LValueExprEvaluator::VisitArraySubs
   if (E->getBase()->getType()->isVectorType())
 return Error(E);
 
-  if (!evaluatePointer(E->getBase(), Result))
-return false;
+  bool Success = true;
+  if (!evaluatePointer(E->getBase(), Result)) {
+if (!Info.noteFailure())
+  return false;
+Success = false;
+  }
 
   APSInt Index;
   if (!EvaluateInteger(E->getIdx(), Index, Info))
 return false;
 
-  return HandleLValueArrayAdjustment(Info, E, Result, E->getType(), Index);
+  return Success &&
+ HandleLValueArrayAdjustment(Info, E, Result, E->getType(), Index);
 }
 
 bool LValueExprEvaluator::VisitUnaryDeref(const UnaryOperator *E) {

Modified: cfe/trunk/test/Sema/integer-overflow.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=301522&r1=301521&r2=301522&view=diff
==
--- cfe/trunk/test/Sema/integer-overflow.c (original)
+++ cfe/trunk/test/Sema/integer-overflow.c Thu Apr 27 02:27:36 2017
@@ -147,6 +147,10 @@ uint64_t check_integer_overflows(int i)
   uint64_t a[10];
   a[4608 * 1024 * 1024] = 1i;
 
+// expected-warning@+2 {{overflow in expression; result is 536870912 with type 
'int'}}
+  uint64_t *b;
+  uint64_t b2 = b[4608 * 1024 * 1024] + 1;
+
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}}
   (void)((i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024)) + 1);
 


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


r301721 - ObjCBoxedExpr can't be evaluated by the constant expression evaluator.

2017-04-28 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Fri Apr 28 19:07:27 2017
New Revision: 301721

URL: http://llvm.org/viewvc/llvm-project?rev=301721&view=rev
Log:
ObjCBoxedExpr can't be evaluated by the constant expression evaluator.

A boxed expression evaluates its subexpr and then calls an objc method to 
transform it into another value with pointer type. The objc method can never be 
constexpr and therefore this expression can never be evaluated. Fixes a 
miscompile boxing expressions with side-effects.

Also make ObjCBoxedExpr handling a normal part of the expression evaluator 
instead of being the only case besides full-expression where we check for 
integer overflow.

Added:
cfe/trunk/test/CodeGenObjCXX/boxing.mm
Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=301721&r1=301720&r2=301721&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Fri Apr 28 19:07:27 2017
@@ -5481,8 +5481,11 @@ public:
   bool VisitUnaryAddrOf(const UnaryOperator *E);
   bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
   { return Success(E); }
-  bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
-  { return Success(E); }
+  bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
+if (Info.noteFailure())
+  EvaluateIgnoredValue(Info, E->getSubExpr());
+return Error(E);
+  }
   bool VisitAddrLabelExpr(const AddrLabelExpr *E)
   { return Success(E); }
   bool VisitCallExpr(const CallExpr *E);

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=301721&r1=301720&r2=301721&view=diff
==
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Apr 28 19:07:27 2017
@@ -9882,6 +9882,9 @@ void Sema::CheckForIntOverflow (Expr *E)
 
 if (auto InitList = dyn_cast(E))
   Exprs.append(InitList->inits().begin(), InitList->inits().end());
+
+if (isa(E))
+  E->IgnoreParenCasts()->EvaluateForOverflow(Context);
   } while (!Exprs.empty());
 }
 

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=301721&r1=301720&r2=301721&view=diff
==
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Fri Apr 28 19:07:27 2017
@@ -595,7 +595,6 @@ ExprResult Sema::BuildObjCBoxedExpr(Sour
 break;
   }
 }
-CheckForIntOverflow(ValueExpr);
 // FIXME:  Do I need to do anything special with BoolTy expressions?
 
 // Look for the appropriate method within NSNumber.

Added: cfe/trunk/test/CodeGenObjCXX/boxing.mm
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjCXX/boxing.mm?rev=301721&view=auto
==
--- cfe/trunk/test/CodeGenObjCXX/boxing.mm (added)
+++ cfe/trunk/test/CodeGenObjCXX/boxing.mm Fri Apr 28 19:07:27 2017
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -o - %s | 
FileCheck %s
+
+@interface NSNumber
++ (id)numberWithInt:(int)n;
+@end
+
+int n = 1;
+int m = (@(n++), 0);
+
+// CHECK: define {{.*}} @__cxx_global_var_init()
+// CHECK: load i32, i32* @n
+// CHECK: store i32 %{{.*}}, i32* @n


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


r301742 - Remove Sema::CheckForIntOverflow, and instead check all full-expressions.

2017-04-29 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Sat Apr 29 04:33:46 2017
New Revision: 301742

URL: http://llvm.org/viewvc/llvm-project?rev=301742&view=rev
Log:
Remove Sema::CheckForIntOverflow, and instead check all full-expressions.

CheckForIntOverflow used to implement a whitelist of top-level expressions to
send to the constant expression evaluator, which handled many more expressions
than the CheckForIntOverflow whitelist did.

Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/distribute_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/parallel_for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/target_simd_aligned_messages.cpp

cfe/trunk/test/OpenMP/target_teams_distribute_parallel_for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/target_teams_distribute_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/taskloop_simd_aligned_messages.cpp

cfe/trunk/test/OpenMP/teams_distribute_parallel_for_simd_aligned_messages.cpp
cfe/trunk/test/OpenMP/teams_distribute_simd_aligned_messages.cpp
cfe/trunk/test/Sema/integer-overflow.c

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=301742&r1=301741&r2=301742&view=diff
==
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sat Apr 29 04:33:46 2017
@@ -10160,7 +10160,6 @@ private:
   void CheckFloatComparison(SourceLocation Loc, Expr* LHS, Expr* RHS);
   void CheckImplicitConversions(Expr *E, SourceLocation CC = SourceLocation());
   void CheckBoolLikeConversion(Expr *E, SourceLocation CC);
-  void CheckForIntOverflow(Expr *E);
   void CheckUnsequencedOperations(Expr *E);
 
   /// \brief Perform semantic checks on a completed expression. This will 
either

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=301742&r1=301741&r2=301742&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sat Apr 29 04:33:46 2017
@@ -6217,6 +6217,10 @@ bool RecordExprEvaluator::VisitInitListE
 // the initializer list.
 ImplicitValueInitExpr VIE(HaveInit ? Info.Ctx.IntTy : Field->getType());
 const Expr *Init = HaveInit ? E->getInit(ElementNo++) : &VIE;
+if (Init->isValueDependent()) {
+  Success = false;
+  continue;
+}
 
 // Temporarily override This, in case there's a CXXDefaultInitExpr in here.
 ThisOverrideRAII ThisOverride(*Info.CurrentCall, &This,
@@ -9927,7 +9931,8 @@ static bool EvaluateAsRValue(EvalInfo &I
 }
 
 static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result,
- const ASTContext &Ctx, bool &IsConst) {
+ const ASTContext &Ctx, bool &IsConst,
+ bool IsCheckingForOverflow) {
   // Fast-path evaluations of integer literals, since we sometimes see files
   // containing vast quantities of these.
   if (const IntegerLiteral *L = dyn_cast(Exp)) {
@@ -9948,7 +9953,7 @@ static bool FastEvaluateAsRValue(const E
   // performance problems. Only do so in C++11 for now.
   if (Exp->isRValue() && (Exp->getType()->isArrayType() ||
   Exp->getType()->isRecordType()) &&
-  !Ctx.getLangOpts().CPlusPlus11) {
+  !Ctx.getLangOpts().CPlusPlus11 && !IsCheckingForOverflow) {
 IsConst = false;
 return true;
   }
@@ -9963,7 +9968,7 @@ static bool FastEvaluateAsRValue(const E
 /// will be applied to the result.
 bool Expr::EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx) const {
   bool IsConst;
-  if (FastEvaluateAsRValue(this, Result, Ctx, IsConst))
+  if (FastEvaluateAsRValue(this, Result, Ctx, IsConst, false))
 return IsConst;
   
   EvalInfo Info(Ctx, Result, EvalInfo::EM_IgnoreSideEffects);
@@ -10088,7 +10093,7 @@ APSInt Expr::EvaluateKnownConstInt(const
 void Expr::EvaluateForOverflow(const ASTContext &Ctx) const {
   bool IsConst;
   EvalResult EvalResult;
-  if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst)) {
+  if (!FastEvaluateAsRValue(this, EvalResult, Ctx, IsConst, true)) {
 EvalInfo Info(Ctx, EvalResult, EvalInfo::EM_EvaluateForOverflow);
 (void)::EvaluateAsRValue(Info, this, EvalResult.Val);
   }

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=301742&r1=301741&r2=301742&view=diff
===

r301785 - Handle expressions with non-literal types like ignored expressions if we are supposed to continue evaluating them.

2017-04-30 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Sun Apr 30 21:03:23 2017
New Revision: 301785

URL: http://llvm.org/viewvc/llvm-project?rev=301785&view=rev
Log:
Handle expressions with non-literal types like ignored expressions if we are 
supposed to continue evaluating them.

Also fix a crash casting a derived nullptr to a virtual base.

Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/Sema/integer-overflow.c
cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=301785&r1=301784&r2=301785&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sun Apr 30 21:03:23 2017
@@ -2169,6 +2169,9 @@ static bool HandleLValueBase(EvalInfo &I
   if (!Base->isVirtual())
 return HandleLValueDirectBase(Info, E, Obj, DerivedDecl, BaseDecl);
 
+  if (!Obj.checkNullPointer(Info, E, CSK_Base))
+return false;
+
   SubobjectDesignator &D = Obj.Designator;
   if (D.Invalid)
 return false;
@@ -9913,8 +9916,11 @@ static bool EvaluateAsRValue(EvalInfo &I
   if (E->getType().isNull())
 return false;
 
-  if (!CheckLiteralType(Info, E))
+  if (!CheckLiteralType(Info, E)) {
+if (Info.noteFailure())
+  EvaluateIgnoredValue(Info, E);
 return false;
+  }
 
   if (!::Evaluate(Result, Info, E))
 return false;

Modified: cfe/trunk/test/Sema/integer-overflow.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=301785&r1=301784&r2=301785&view=diff
==
--- cfe/trunk/test/Sema/integer-overflow.c (original)
+++ cfe/trunk/test/Sema/integer-overflow.c Sun Apr 30 21:03:23 2017
@@ -149,16 +149,16 @@ uint64_t check_integer_overflows(int i)
 
 // expected-warning@+2 {{overflow in expression; result is 536870912 with type 
'int'}}
   uint64_t *b;
-  uint64_t b2 = b[4608 * 1024 * 1024] + 1;
+  (void)b[4608 * 1024 * 1024] + 1;
 
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}}
-  int j1 = i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024);
+  (void)(i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024));
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 
'int'}}
-  int j2 = -(4608 * 1024 * 1024);
+  (void)(-(4608 * 1024 * 1024));
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 
'int'}}
-  uint64_t j3 = b[4608 * 1024 * 1024];
+  (void)b[4608 * 1024 * 1024];
 
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}}
   return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=301785&r1=301784&r2=301785&view=diff
==
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Sun Apr 30 21:03:23 
2017
@@ -60,6 +60,10 @@ namespace DerivedToVBaseCast {
   static_assert((U*)&d == w, "");
   static_assert((U*)&d == x, "");
 
+  // expected-error@+2 {{constexpr variable 'a' must be initialized by a 
constant expression}}
+  // expected-warning@+1 {{binding dereferenced null pointer to reference has 
undefined behavior}}
+  constexpr A &a = *((B*)0);  // expected-note {{cannot access base class of 
null pointer}}
+
   struct X {};
   struct Y1 : virtual X {};
   struct Y2 : X {};


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


r301787 - Fix test that was incorrected merged between patches.

2017-04-30 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Sun Apr 30 21:20:06 2017
New Revision: 301787

URL: http://llvm.org/viewvc/llvm-project?rev=301787&view=rev
Log:
Fix test that was incorrected merged between patches.

Modified:
cfe/trunk/test/Sema/integer-overflow.c

Modified: cfe/trunk/test/Sema/integer-overflow.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=301787&r1=301786&r2=301787&view=diff
==
--- cfe/trunk/test/Sema/integer-overflow.c (original)
+++ cfe/trunk/test/Sema/integer-overflow.c Sun Apr 30 21:20:06 2017
@@ -149,7 +149,7 @@ uint64_t check_integer_overflows(int i)
 
 // expected-warning@+2 {{overflow in expression; result is 536870912 with type 
'int'}}
   uint64_t *b;
-  (void)b[4608 * 1024 * 1024] + 1;
+  (void)b[4608 * 1024 * 1024];
 
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}}
   (void)(i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024));


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


r301891 - Revert r301785 (and r301787) because they caused PR32864.

2017-05-01 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Mon May  1 20:06:16 2017
New Revision: 301891

URL: http://llvm.org/viewvc/llvm-project?rev=301891&view=rev
Log:
Revert r301785 (and r301787) because they caused PR32864.

The fix is that ExprEvaluatorBase::VisitInitListExpr should handle transparent 
exprs instead of exprs with one element. Fixing that uncovers one testcase 
failure because the AST for "constexpr _Complex float test2 = {1};" is wrong 
(the _Complex prvalue should not be const-qualified), and a number of test 
failures in test/OpenMP where the captured stmt contains an InitListExpr that 
is in syntactic form.

Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/Sema/integer-overflow.c
cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=301891&r1=301890&r2=301891&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon May  1 20:06:16 2017
@@ -2186,9 +2186,6 @@ static bool HandleLValueBase(EvalInfo &I
   if (!Base->isVirtual())
 return HandleLValueDirectBase(Info, E, Obj, DerivedDecl, BaseDecl);
 
-  if (!Obj.checkNullPointer(Info, E, CSK_Base))
-return false;
-
   SubobjectDesignator &D = Obj.Designator;
   if (D.Invalid)
 return false;
@@ -9946,11 +9943,8 @@ static bool EvaluateAsRValue(EvalInfo &I
   if (E->getType().isNull())
 return false;
 
-  if (!CheckLiteralType(Info, E)) {
-if (Info.noteFailure())
-  EvaluateIgnoredValue(Info, E);
+  if (!CheckLiteralType(Info, E))
 return false;
-  }
 
   if (!::Evaluate(Result, Info, E))
 return false;

Modified: cfe/trunk/test/Sema/integer-overflow.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=301891&r1=301890&r2=301891&view=diff
==
--- cfe/trunk/test/Sema/integer-overflow.c (original)
+++ cfe/trunk/test/Sema/integer-overflow.c Mon May  1 20:06:16 2017
@@ -149,16 +149,16 @@ uint64_t check_integer_overflows(int i)
 
 // expected-warning@+2 {{overflow in expression; result is 536870912 with type 
'int'}}
   uint64_t *b;
-  (void)b[4608 * 1024 * 1024];
+  uint64_t b2 = b[4608 * 1024 * 1024] + 1;
 
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}}
-  (void)(i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024));
+  int j1 = i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024);
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 
'int'}}
-  (void)(-(4608 * 1024 * 1024));
+  int j2 = -(4608 * 1024 * 1024);
 
 // expected-warning@+1 {{overflow in expression; result is 536870912 with type 
'int'}}
-  (void)b[4608 * 1024 * 1024];
+  uint64_t j3 = b[4608 * 1024 * 1024];
 
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}}
   return ((4608 * 1024 * 1024) + ((uint64_t)(4608 * 1024 * 1024)));

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=301891&r1=301890&r2=301891&view=diff
==
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Mon May  1 20:06:16 
2017
@@ -60,10 +60,6 @@ namespace DerivedToVBaseCast {
   static_assert((U*)&d == w, "");
   static_assert((U*)&d == x, "");
 
-  // expected-error@+2 {{constexpr variable 'a' must be initialized by a 
constant expression}}
-  // expected-warning@+1 {{binding dereferenced null pointer to reference has 
undefined behavior}}
-  constexpr A &a = *((B*)0);  // expected-note {{cannot access base class of 
null pointer}}
-
   struct X {};
   struct Y1 : virtual X {};
   struct Y2 : X {};


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


r303317 - The constant expression evaluator should examine function arguments for non-constexpr function calls unless the EvalInfo says to stop.

2017-05-17 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Wed May 17 18:56:54 2017
New Revision: 303317

URL: http://llvm.org/viewvc/llvm-project?rev=303317&view=rev
Log:
The constant expression evaluator should examine function arguments for 
non-constexpr function calls unless the EvalInfo says to stop.

Modified:
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/test/Sema/integer-overflow.c

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=303317&r1=303316&r2=303317&view=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Wed May 17 18:56:54 2017
@@ -4579,7 +4579,7 @@ public:
   }
 
   bool handleCallExpr(const CallExpr *E, APValue &Result,
- const LValue *ResultSlot) {
+  const LValue *ResultSlot) {
 const Expr *Callee = E->getCallee()->IgnoreParens();
 QualType CalleeType = Callee->getType();
 
@@ -4588,6 +4588,23 @@ public:
 auto Args = llvm::makeArrayRef(E->getArgs(), E->getNumArgs());
 bool HasQualifier = false;
 
+struct EvaluateIgnoredRAII {
+public:
+  EvaluateIgnoredRAII(EvalInfo &Info, llvm::ArrayRef ToEval)
+  : Info(Info), ToEval(ToEval) {}
+  ~EvaluateIgnoredRAII() {
+if (Info.noteFailure()) {
+  for (auto E : ToEval)
+EvaluateIgnoredValue(Info, E);
+}
+  }
+  void cancel() { ToEval = {}; }
+  void drop_front() { ToEval = ToEval.drop_front(); }
+private:
+  EvalInfo &Info;
+  llvm::ArrayRef ToEval;
+} EvalArguments(Info, Args);
+
 // Extract function decl and 'this' pointer from the callee.
 if (CalleeType->isSpecificBuiltinType(BuiltinType::BoundMember)) {
   const ValueDecl *Member = nullptr;
@@ -4637,10 +4654,12 @@ public:
 if (Args.empty())
   return Error(E);
 
-if (!EvaluateObjectArgument(Info, Args[0], ThisVal))
+const Expr *FirstArg = Args[0];
+Args = Args.drop_front();
+EvalArguments.drop_front();
+if (!EvaluateObjectArgument(Info, FirstArg, ThisVal))
   return false;
 This = &ThisVal;
-Args = Args.slice(1);
   } else if (MD && MD->isLambdaStaticInvoker()) {   
 // Map the static invoker for the lambda back to the call operator.
 // Conveniently, we don't have to slice out the 'this' argument (as is
@@ -4692,8 +4711,12 @@ public:
 const FunctionDecl *Definition = nullptr;
 Stmt *Body = FD->getBody(Definition);
 
-if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body) ||
-!HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, 
Info,
+if (!CheckConstexprFunction(Info, E->getExprLoc(), FD, Definition, Body))
+  return false;
+
+EvalArguments.cancel();
+
+if (!HandleFunctionCall(E->getExprLoc(), Definition, This, Args, Body, 
Info,
 Result, ResultSlot))
   return false;
 

Modified: cfe/trunk/test/Sema/integer-overflow.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/integer-overflow.c?rev=303317&r1=303316&r2=303317&view=diff
==
--- cfe/trunk/test/Sema/integer-overflow.c (original)
+++ cfe/trunk/test/Sema/integer-overflow.c Wed May 17 18:56:54 2017
@@ -151,6 +151,14 @@ uint64_t check_integer_overflows(int i)
   uint64_t *b;
   uint64_t b2 = b[4608 * 1024 * 1024] + 1;
 
+// expected-warning@+1 {{overflow in expression; result is 536870912 with type 
'int'}} 
+  f0(4608 * 1024 * 1024);
+  f0(4608ul * 1024 * 1024);
+// expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}} 
+  f1(4608 * 1024 * 1024, 4608 * 1024 * 1024);
+// expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}} 
+  f2(4608 * 1024 * 1024, 4608 * 1024 * 1024);
+
 // expected-warning@+1 2{{overflow in expression; result is 536870912 with 
type 'int'}}
   int j1 = i ? (4608 * 1024 * 1024) : (4608 * 1024 * 1024);
 


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


Re: [PATCH] D12719: ScalarEvolution assume hanging bugfix

2015-09-08 Thread Nick Lewycky via cfe-commits
nlewycky added inline comments.


Comment at: lib/Analysis/ScalarEvolution.cpp:6980
@@ -6991,1 +6979,3 @@
 
+  // Check conditions due to any @llvm.assume intrinsics.
+  for (auto &AssumeVH : AC.assumptions()) {

What is it about this check which is a problem? Or put another way, why is this 
not okay but the call to isImpliedCond on line 6956 is fine? The problem is 
recursion through isImpliedCond->getSCEV->..., right?


http://reviews.llvm.org/D12719



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


Re: [PATCH] D12719: ScalarEvolution assume hanging bugfix

2015-09-08 Thread Nick Lewycky via cfe-commits
nlewycky added inline comments.


Comment at: lib/Analysis/ScalarEvolution.cpp:6980
@@ -6991,1 +6979,3 @@
 
+  // Check conditions due to any @llvm.assume intrinsics.
+  for (auto &AssumeVH : AC.assumptions()) {

Prazek wrote:
> nlewycky wrote:
> > What is it about this check which is a problem? Or put another way, why is 
> > this not okay but the call to isImpliedCond on line 6956 is fine? The 
> > problem is recursion through isImpliedCond->getSCEV->..., right?
> The problem is that the check wasn't covering assume loop which caused big 
> hang.
> 
> Stacktrace looked more like this
> (isImpliedCond -> getZeroExtendExpr -> isLoopBackedgeGuardedByCond) x much
Does the code from 6953 to 6959 need to move below this check too? Is there 
another bug here?


http://reviews.llvm.org/D12719



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


Re: [PATCH] D12719: ScalarEvolution assume hanging bugfix

2015-09-08 Thread Nick Lewycky via cfe-commits
On 8 September 2015 at 20:27, Sanjoy Das 
wrote:

> sanjoy added a comment.
>
> I don't think this is an infinite loop (Piotr, can you please verify
> this?), it is probably an O(n!) recursion where n == number of the
> assumptions.
>
> ScalarEvolution::isImpliedCond already guards for infinite loops via
> MarkPendingLoopPredicate.  However, if you have
>
> assume_0()
>  assume_1()
>  assume_2()
>  assume_3()
>
> then the recursive call to isImpliedCond(assume_2, X) may end up
> calling isImpliedCond(assume_1, Y) and that may end up calling
> isImpliedCond(assume_0, Y) and that may end up calling
> isImpliedCond(assume_3, Y).  This way, even though we're protected
> against full on infinite recursion, we'll still explore all 4! = 24
> possibilities.
>

I agree it's probably O(n!) instead of infinite, but that's slow enough.

I think the check with LoopContinuePredicate is fine since it only
> calls isImpliedCond if there is exactly one latch in the loop.  This
> means that the above n! possibility is really only a 1! = 1
> possibility for LoopContinuePredicate.
>
> But this from memory, so please double check.
>

Both tests are protected by there being exactly one latch in the loop (we
exit early if there's not one latch). I'm not sure what makes the
LoopContinuePredicate check safer?
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] __attribute__((enable_if)) and non-overloaded member functions

2015-09-16 Thread Nick Lewycky via cfe-commits
+gbiv, would you be able to review this?
On Sep 14, 2015 7:42 AM, "Ettore Speziale" 
wrote:

> Ping
>
> > Gently ping.
> >
> >> On Aug 26, 2015, at 2:40 PM, Ettore Speziale 
> wrote:
> >>
> >> Forward to the right ML:
> >>
>  Sorry about the extreme delay. This patch slipped through the cracks,
> and I only noticed it again when searching my email for enable_if.
> Committed in r245985! In the future, please feel free to continue pinging
> weekly!
> >>>
> >>> NP, thank you for committing the patch.
> >>>
> >>> Unfortunately it contains a little error in the case of no candidate
> has been found. For instance consider the following test case:
> >>>
> >>> struct Incomplete;
> >>>
> >>> struct X {
> >>> void hidden_by_argument_conversion(Incomplete n, int m = 0)
> __attribute((enable_if(m == 10, "chosen when 'm' is ten")));
> >>> };
> >>>
> >>> x.hidden_by_argument_conversion(10);
> >>>
> >>> I would expect to get an error about Incomplete, as the compiler
> cannot understand how to convert 10 into an instance of Incomplete. However
> right now the enable_if diagnostic is emitted, thus masking the more useful
> message about Incomplete.
> >>>
> >>> The attached patch solved the problem by delaying the point where the
> enable_if diagnostic is issued.
> >>>
> >>> Thanks,
> >>> Ettore Speziale
> >>
> >>
> >> 
> >
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D13373: Emiting invariant.group.barrier for ctors bugfix

2015-10-01 Thread Nick Lewycky via cfe-commits
nlewycky added a comment.

I can't meaningfully review this, but I see nothing wrong here.



Comment at: lib/CodeGen/CGClass.cpp:1378
@@ -1377,3 +1377,3 @@
 
-  bool BaseVPtrsInitialized = false;
+  llvm::Value* const OldThis = CXXThisValue;
   // Virtual base initializers first.

"llvm::Value* const" --> "llvm::Value *const"


http://reviews.llvm.org/D13373



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


r244515 - If a variable template is inside a context with template arguments that is being instantiated, and that instantiation fails, fail our instantiation instead of crashing. Errors have already b

2015-08-10 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Mon Aug 10 16:54:08 2015
New Revision: 244515

URL: http://llvm.org/viewvc/llvm-project?rev=244515&view=rev
Log:
If a variable template is inside a context with template arguments that is 
being instantiated, and that instantiation fails, fail our instantiation 
instead of crashing. Errors have already been emitted.

Modified:
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=244515&r1=244514&r2=244515&view=diff
==
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Aug 10 16:54:08 2015
@@ -1143,6 +1143,7 @@ Decl *TemplateDeclInstantiator::VisitVar
   VarDecl *VarInst =
   cast_or_null(VisitVarDecl(Pattern,
  /*InstantiatingVarTemplate=*/true));
+  if (!VarInst) return nullptr;
 
   DeclContext *DC = Owner;
 

Modified: cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp?rev=244515&r1=244514&r2=244515&view=diff
==
--- cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx1y-variable-templates_in_class.cpp Mon Aug 10 
16:54:08 2015
@@ -327,3 +327,14 @@ struct S {
   static int f : I; // expected-error {{static member 'f' cannot be a 
bit-field}}
 };
 }
+
+namespace b20896909 {
+  // This used to crash.
+  template struct helper {};
+  template class A {
+template  static helper x;  // expected-error 
{{type 'int' cannot be used prior to '::' because it has no members}}
+  };
+  void test() {
+A ai;  // expected-note {{in instantiation of}}
+  }
+}


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


patch: clarify diagnostic when returned value doesn't match function return type

2015-08-10 Thread Nick Lewycky via cfe-commits
This simple-minded patch extends the case where we report "no viable
conversion from 'X' to 'Y'" to emit a more useful diagnostic "no viable
conversion from returned value of type 'X' to function return type 'Y'"
when used in that context.

In lieu of adding tests for this diagnostic explicitly, I've only updated
the tests where the patch changes their result.

Please review!

Nick
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 244522)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -5788,7 +5788,8 @@
 def err_typecheck_ambiguous_condition : Error<
   "conversion %diff{from $ to $|between types}0,1 is ambiguous">;
 def err_typecheck_nonviable_condition : Error<
-  "no viable conversion%diff{ from $ to $|}0,1">;
+  "no viable conversion%select{%diff{ from $ to $|}1,2|"
+  "%diff{ from returned value of type $ to function return type $|}1,2}0">;
 def err_typecheck_nonviable_condition_incomplete : Error<
   "no viable conversion%diff{ from $ to incomplete type $|}0,1">;
 def err_typecheck_deleted_function : Error<
Index: lib/Sema/SemaInit.cpp
===
--- lib/Sema/SemaInit.cpp	(revision 244522)
+++ lib/Sema/SemaInit.cpp	(working copy)
@@ -6943,6 +6943,7 @@
   diag::err_typecheck_nonviable_condition_incomplete,
Args[0]->getType(), Args[0]->getSourceRange()))
 S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
+  << (Entity.getKind() == InitializedEntity::EK_Result)
   << Args[0]->getType() << Args[0]->getSourceRange()
   << DestType.getNonReferenceType();
 
Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp	(revision 244522)
+++ lib/Sema/SemaOverload.cpp	(working copy)
@@ -3212,7 +3212,7 @@
  diag::err_typecheck_nonviable_condition_incomplete,
  From->getType(), From->getSourceRange()))
   Diag(From->getLocStart(), diag::err_typecheck_nonviable_condition)
-  << From->getType() << From->getSourceRange() << ToType;
+  << false << From->getType() << From->getSourceRange() << ToType;
   } else
 return false;
   CandidateSet.NoteCandidates(*this, OCD_AllCandidates, From);
Index: test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp
===
--- test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp	(revision 244522)
+++ test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp	(working copy)
@@ -49,7 +49,7 @@
   static double dfi(int i) { return i + 3.14; }
   static Local localfi(int) { return Local{}; }
 };
-auto l4 = [](auto (*fp)(int)) -> int { return fp(3); }; //expected-error{{no viable conversion from 'Local' to 'int'}} 
+auto l4 = [](auto (*fp)(int)) -> int { return fp(3); }; //expected-error{{no viable conversion from returned value of type 'Local' to function return type 'int'}} 
 l4(&Local::ifi);
 l4(&Local::cfi);
 l4(&Local::dfi);
Index: test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
===
--- test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp	(revision 244522)
+++ test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp	(working copy)
@@ -38,7 +38,7 @@
 template
 int infer_result(T x, T y) {
   auto lambda = [=](bool b) { return x + y; };
-  return lambda(true); // expected-error{{no viable conversion from 'X' to 'int'}}
+  return lambda(true); // expected-error{{no viable conversion from returned value of type 'X' to function return type 'int'}}
 }
 
 template int infer_result(int, int);
Index: test/SemaCXX/rval-references.cpp
===
--- test/SemaCXX/rval-references.cpp	(revision 244522)
+++ test/SemaCXX/rval-references.cpp	(working copy)
@@ -90,5 +90,5 @@
   else if (0) // Copy from reference can't be elided
 return r; // expected-error {{call to deleted constructor}}
   else // Construction from different type can't be elided
-return i; // expected-error {{no viable conversion from 'int' to 'MoveOnly'}}
+return i; // expected-error {{no viable conversion from returned value of type 'int' to function return type 'MoveOnly'}}
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: patch: clarify diagnostic when returned value doesn't match function return type

2015-08-19 Thread Nick Lewycky via cfe-commits
On 10 August 2015 at 19:08, Nick Lewycky  wrote:

> This simple-minded patch extends the case where we report "no viable
> conversion from 'X' to 'Y'" to emit a more useful diagnostic "no viable
> conversion from returned value of type 'X' to function return type 'Y'"
> when used in that context.
>
> In lieu of adding tests for this diagnostic explicitly, I've only updated
> the tests where the patch changes their result.
>
> Please review!
>

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


Re: patch: clarify diagnostic when returned value doesn't match function return type

2015-08-24 Thread Nick Lewycky via cfe-commits
On 19 August 2015 at 15:18, Nick Lewycky  wrote:

> On 10 August 2015 at 19:08, Nick Lewycky  wrote:
>
>> This simple-minded patch extends the case where we report "no viable
>> conversion from 'X' to 'Y'" to emit a more useful diagnostic "no viable
>> conversion from returned value of type 'X' to function return type 'Y'"
>> when used in that context.
>>
>> In lieu of adding tests for this diagnostic explicitly, I've only updated
>> the tests where the patch changes their result.
>>
>> Please review!
>>
>
> Ping!
>

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


r245979 - Clarify the error message when the reason the conversion is not viable is because the returned value does not match the function return type.

2015-08-25 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Tue Aug 25 17:18:46 2015
New Revision: 245979

URL: http://llvm.org/viewvc/llvm-project?rev=245979&view=rev
Log:
Clarify the error message when the reason the conversion is not viable is 
because the returned value does not match the function return type.

Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp

cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
cfe/trunk/test/SemaCXX/rval-references.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=245979&r1=245978&r2=245979&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Aug 25 17:18:46 
2015
@@ -5792,7 +5792,8 @@ def err_typecheck_bool_condition : Error
 def err_typecheck_ambiguous_condition : Error<
   "conversion %diff{from $ to $|between types}0,1 is ambiguous">;
 def err_typecheck_nonviable_condition : Error<
-  "no viable conversion%diff{ from $ to $|}0,1">;
+  "no viable conversion%select{%diff{ from $ to $|}1,2|"
+  "%diff{ from returned value of type $ to function return type $|}1,2}0">;
 def err_typecheck_nonviable_condition_incomplete : Error<
   "no viable conversion%diff{ from $ to incomplete type $|}0,1">;
 def err_typecheck_deleted_function : Error<

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=245979&r1=245978&r2=245979&view=diff
==
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Tue Aug 25 17:18:46 2015
@@ -6946,6 +6946,7 @@ bool InitializationSequence::Diagnose(Se
   diag::err_typecheck_nonviable_condition_incomplete,
Args[0]->getType(), Args[0]->getSourceRange()))
 S.Diag(Kind.getLocation(), diag::err_typecheck_nonviable_condition)
+  << (Entity.getKind() == InitializedEntity::EK_Result)
   << Args[0]->getType() << Args[0]->getSourceRange()
   << DestType.getNonReferenceType();
 

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=245979&r1=245978&r2=245979&view=diff
==
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Aug 25 17:18:46 2015
@@ -3212,7 +3212,7 @@ Sema::DiagnoseMultipleUserDefinedConvers
  
diag::err_typecheck_nonviable_condition_incomplete,
  From->getType(), From->getSourceRange()))
   Diag(From->getLocStart(), diag::err_typecheck_nonviable_condition)
-  << From->getType() << From->getSourceRange() << ToType;
+  << false << From->getType() << From->getSourceRange() << ToType;
   } else
 return false;
   CandidateSet.NoteCandidates(*this, OCD_AllCandidates, From);

Modified: 
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp?rev=245979&r1=245978&r2=245979&view=diff
==
--- 
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp
 (original)
+++ 
cfe/trunk/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3-generic-lambda-1y.cpp
 Tue Aug 25 17:18:46 2015
@@ -49,7 +49,7 @@ int main()
   static double dfi(int i) { return i + 3.14; }
   static Local localfi(int) { return Local{}; }
 };
-auto l4 = [](auto (*fp)(int)) -> int { return fp(3); }; 
//expected-error{{no viable conversion from 'Local' to 'int'}} 
+auto l4 = [](auto (*fp)(int)) -> int { return fp(3); }; 
//expected-error{{no viable conversion from returned value of type 'Local' to 
function return type 'int'}} 
 l4(&Local::ifi);
 l4(&Local::cfi);
 l4(&Local::dfi);

Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp?rev=245979&r1=245978&r2=245979&view=diff
==
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/templates.cpp Tue Aug 25 
17:18:46 2015
@@ -38,7 +38,7 @@ template X captures(X, X);
 template
 int infer_result(T x, T y) {
   auto lambda = [=](bo

r245985 - Make sure that we evaluate __attribute__((enable_if)) on a method with no overloads. Patch by Ettore Speziale!

2015-08-25 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Tue Aug 25 17:33:16 2015
New Revision: 245985

URL: http://llvm.org/viewvc/llvm-project?rev=245985&view=rev
Log:
Make sure that we evaluate __attribute__((enable_if)) on a method with no 
overloads. Patch by Ettore Speziale!

Modified:
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/SemaCXX/enable_if.cpp

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=245985&r1=245984&r2=245985&view=diff
==
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Aug 25 17:33:16 2015
@@ -5826,10 +5826,11 @@ EnableIfAttr *Sema::CheckEnableIf(Functi
 
   SFINAETrap Trap(*this);
 
-  // Convert the arguments.
   SmallVector ConvertedArgs;
   bool InitializationFailed = false;
   bool ContainsValueDependentExpr = false;
+
+  // Convert the arguments.
   for (unsigned i = 0, e = Args.size(); i != e; ++i) {
 if (i == 0 && !MissingImplicitThis && isa(Function) &&
 !cast(Function)->isStatic() &&
@@ -5863,6 +5864,28 @@ EnableIfAttr *Sema::CheckEnableIf(Functi
   if (InitializationFailed || Trap.hasErrorOccurred())
 return cast(Attrs[0]);
 
+  // Push default arguments if needed.
+  if (!Function->isVariadic() && Args.size() < Function->getNumParams()) {
+for (unsigned i = Args.size(), e = Function->getNumParams(); i != e; ++i) {
+  ParmVarDecl *P = Function->getParamDecl(i);
+  ExprResult R = PerformCopyInitialization(
+  InitializedEntity::InitializeParameter(Context,
+ Function->getParamDecl(i)),
+  SourceLocation(),
+  P->hasUninstantiatedDefaultArg() ? P->getUninstantiatedDefaultArg()
+   : P->getDefaultArg());
+  if (R.isInvalid()) {
+InitializationFailed = true;
+break;
+  }
+  ContainsValueDependentExpr |= R.get()->isValueDependent();
+  ConvertedArgs.push_back(R.get());
+}
+
+if (InitializationFailed || Trap.hasErrorOccurred())
+  return cast(Attrs[0]);
+  }
+
   for (AttrVec::iterator I = Attrs.begin(); I != E; ++I) {
 APValue Result;
 EnableIfAttr *EIA = cast(*I);
@@ -11604,6 +11627,16 @@ Sema::BuildCallToMemberFunction(Scope *S
 FoundDecl = MemExpr->getFoundDecl();
 Qualifier = MemExpr->getQualifier();
 UnbridgedCasts.restore();
+
+if (const EnableIfAttr *Attr = CheckEnableIf(Method, Args, true)) {
+  Diag(MemExprE->getLocStart(),
+   diag::err_ovl_no_viable_member_function_in_call)
+  << Method << Method->getSourceRange();
+  Diag(Method->getLocation(),
+   diag::note_ovl_candidate_disabled_by_enable_if_attr)
+  << Attr->getCond()->getSourceRange() << Attr->getMessage();
+  return ExprError();
+}
   } else {
 UnresolvedMemberExpr *UnresExpr = cast(NakedMemExpr);
 Qualifier = UnresExpr->getQualifier();

Modified: cfe/trunk/test/SemaCXX/enable_if.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/enable_if.cpp?rev=245985&r1=245984&r2=245985&view=diff
==
--- cfe/trunk/test/SemaCXX/enable_if.cpp (original)
+++ cfe/trunk/test/SemaCXX/enable_if.cpp Tue Aug 25 17:33:16 2015
@@ -11,6 +11,10 @@ struct X {
   void f(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero")));
   void f(int n) __attribute__((enable_if(n == 1, "chosen when 'n' is one")));  
// expected-note{{member declaration nearly matches}} expected-note{{candidate 
disabled: chosen when 'n' is one}}
 
+  void g(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is zero"))); 
 // expected-note{{candidate disabled: chosen when 'n' is zero}}
+
+  void h(int n, int m = 0) __attribute((enable_if(m == 0, "chosen when 'm' is 
zero")));  // expected-note{{candidate disabled: chosen when 'm' is zero}}
+
   static void s(int n) __attribute__((enable_if(n == 0, "chosen when 'n' is 
zero")));  // expected-note2{{candidate disabled: chosen when 'n' is zero}}
 
   void conflict(int n) __attribute__((enable_if(n+n == 10, "chosen when 'n' is 
five")));  // expected-note{{candidate function}}
@@ -40,6 +44,15 @@ void deprec2(int i) __attribute__((enabl
 void overloaded(int);
 void overloaded(long);
 
+struct Int {
+  constexpr Int(int i) : i(i) { }
+  constexpr operator int() const { return i; }
+  int i;
+};
+
+void default_argument(int n, int m = 0) __attribute__((enable_if(m == 0, 
"chosen when 'm' is zero")));  // expected-note{{candidate disabled: chosen 
when 'm' is zero}}
+void default_argument_promotion(int n, int m = Int(0)) 
__attribute__((enable_if(m == 0, "chosen when 'm' is zero")));  // 
expected-note{{candidate disabled: chosen when 'm' is zero}}
+
 struct Nothing { };
 template void typedep(T t) __attribute__((enable_if(t, "")));  // 
expected-note{{candidate disabled:}}  

Fwd: [PATCH] __attribute__((enable_if)) and non-overloaded member functions

2015-08-26 Thread Nick Lewycky via cfe-commits
--> lists.llvm.org

-- Forwarded message --
From: Ettore Speziale 
Date: 26 August 2015 at 14:35
Subject: Re: [PATCH] __attribute__((enable_if)) and non-overloaded member
functions
To: Nick Lewycky 
Cc: llvm cfe 


Hello,

> Sorry about the extreme delay. This patch slipped through the cracks, and
I only noticed it again when searching my email for enable_if. Committed in
r245985! In the future, please feel free to continue pinging weekly!

NP, thank you for committing the patch.

Unfortunately it contains a little error in the case of no candidate has
been found. For instance consider the following test case:

struct Incomplete;

struct X {
void hidden_by_argument_conversion(Incomplete n, int m = 0)
__attribute((enable_if(m == 10, "chosen when 'm' is ten")));
};

x.hidden_by_argument_conversion(10);

I would expect to get an error about Incomplete, as the compiler cannot
understand how to convert 10 into an instance of Incomplete. However right
now the enable_if diagnostic is emitted, thus masking the more useful
message about Incomplete.

The attached patch solved the problem by delaying the point where the
enable_if diagnostic is issued.

Thanks,
Ettore Speziale


enable_if.diff
Description: Binary data
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


r250666 - No functionality change, just fix whitespace, a typo and remove an unnecessary

2015-10-18 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Sun Oct 18 15:32:12 2015
New Revision: 250666

URL: http://llvm.org/viewvc/llvm-project?rev=250666&view=rev
Log:
No functionality change, just fix whitespace, a typo and remove an unnecessary
emacs mode marker. (Changes left behind from another patch that ended up not
working out.)

Modified:
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=250666&r1=250665&r2=250666&view=diff
==
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Sun Oct 18 15:32:12 2015
@@ -1233,7 +1233,7 @@ void DeclContext::addHiddenDecl(Decl *D)
   }
 
   // Notify a C++ record declaration that we've added a member, so it can
-  // update it's class-specific state.
+  // update its class-specific state.
   if (CXXRecordDecl *Record = dyn_cast(this))
 Record->addedMember(D);
 

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=250666&r1=250665&r2=250666&view=diff
==
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Sun Oct 18 15:32:12 2015
@@ -1,4 +1,4 @@
-//===- SemaLookup.cpp - Name Lookup  *- C++ 
-*-===//
+//===- SemaLookup.cpp - Name Lookup  
--===//
 //
 // The LLVM Compiler Infrastructure
 //
@@ -154,7 +154,7 @@ namespace {
 // by its using directives, transitively) as if they appeared in
 // the given effective context.
 void addUsingDirectives(DeclContext *DC, DeclContext *EffectiveDC) {
-  SmallVector queue;
+  SmallVector queue;
   while (true) {
 for (auto UD : DC->using_directives()) {
   DeclContext *NS = UD->getNominatedNamespace();
@@ -2189,7 +2189,7 @@ void Sema::DiagnoseAmbiguousLookup(Looku
   case LookupResult::AmbiguousTagHiding: {
 Diag(NameLoc, diag::err_ambiguous_tag_hiding) << Name << LookupRange;
 
-llvm::SmallPtrSet TagDecls;
+llvm::SmallPtrSet TagDecls;
 
 for (auto *D : Result)
   if (TagDecl *TD = dyn_cast(D)) {

Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=250666&r1=250665&r2=250666&view=diff
==
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Sun Oct 18 15:32:12 2015
@@ -260,7 +260,7 @@ void ASTDeclWriter::Visit(Decl *D) {
   // Source locations require array (variable-length) abbreviations.  The
   // abbreviation infrastructure requires that arrays are encoded last, so
   // we handle it here in the case of those classes derived from DeclaratorDecl
-  if (DeclaratorDecl *DD = dyn_cast(D)){
+  if (DeclaratorDecl *DD = dyn_cast(D)) {
 Writer.AddTypeSourceInfo(DD->getTypeSourceInfo(), Record);
   }
 
@@ -2101,7 +2101,7 @@ void ASTWriter::WriteDecl(ASTContext &Co
 if (IDR == 0)
   IDR = NextDeclID++;
 
-ID= IDR;
+ID = IDR;
   }
 
   bool isReplacingADecl = ID < FirstDeclID;


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


r244490 - Fix typo.

2015-08-10 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Mon Aug 10 14:54:11 2015
New Revision: 244490

URL: http://llvm.org/viewvc/llvm-project?rev=244490&view=rev
Log:
Fix typo.

Modified:
cfe/trunk/docs/LanguageExtensions.rst

Modified: cfe/trunk/docs/LanguageExtensions.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.rst?rev=244490&r1=244489&r2=244490&view=diff
==
--- cfe/trunk/docs/LanguageExtensions.rst (original)
+++ cfe/trunk/docs/LanguageExtensions.rst Mon Aug 10 14:54:11 2015
@@ -415,7 +415,7 @@ dash indicates that an operation is not
 specification.
 
 == === === === ===
- Opeator   OpenCL  AltiVec   GCCNEON
+ Operator  OpenCL  AltiVec   GCCNEON
 == === === === ===
 []   yes yes yes --
 unary operators +, --yes yes yes --


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


Re: [PATCH] D22900: Revert r244207 - Mark calls in thunk functions as tail-call optimization

2016-08-09 Thread Nick Lewycky via cfe-commits
nlewycky added a comment.

For the IR level, I think this has got to be valid:

  declare void @bar(i32* byval %p)
  define void @foo(i32* byval %p) {
tail call void @bar(i32* byval %p.tmp)
ret void
  }

The `tail` is an aliasing property which indicates that the callee doesn't 
touch any of the alloca's in the caller, a rough proxy for "stack" since there 
is no other stack in LLVM IR. That doesn't mean that we're going to actually 
lower it to a tail call in the final assembly, but if we don't put `tail` on a 
call, we won't even consider it for becoming a tail call. I think the backend 
can sort out whether the byval is going to lead to a stack allocation in @foo 
and emit a non-tail call if so.


https://reviews.llvm.org/D22900



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


Re: [PATCH] D19586: Misleading Indentation check

2016-04-27 Thread Nick Lewycky via cfe-commits
nlewycky added a subscriber: nlewycky.


Comment at: clang-tidy/readability/MisleadingIndentationCheck.cpp:31
@@ +30,3 @@
+  Result.SourceManager->getExpansionColumnNumber(ElseLoc))
+diag(ElseLoc, "potentional dangling else");
+}

Typo of "potential" as "potentional".


Comment at: clang-tidy/readability/MisleadingIndentationCheck.cpp:54
@@ +53,3 @@
+
+if (Result.SourceManager->getExpansionColumnNumber(StmtLoc) ==
+Result.SourceManager->getExpansionColumnNumber(NextLoc))

What about a one-line "if (x) foo(); else bar();"? Warn on it anyways?


Comment at: clang-tidy/readability/MisleadingIndentationCheck.cpp:56
@@ +55,3 @@
+Result.SourceManager->getExpansionColumnNumber(NextLoc))
+  diag(NextLoc, "Wrong Indentation - statement is indentated as a member "
+"of if statement");

Typo of "indented" as "indentated".


Comment at: test/clang-tidy/readability-misleading-indentation.cpp:48
@@ +47,3 @@
+   }
+  foo2();  // ok
+

This is arguably misleading indentation, but I'm ok with not warning on it if 
you think it will cause too many false positives.


http://reviews.llvm.org/D19586



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


[PATCH] D19851: Warn on binding reference to null in copy initialization

2016-05-02 Thread Nick Lewycky via cfe-commits
nicholas created this revision.
nicholas added a reviewer: cfe-commits.

The attached patch adds a warning when placing a call like:
  func(*static_cast(nullptr));
to the existing -Wnull-dereference warning.

The existing warning catches the case where the empty lvalue undergoes 
lvalue-to-rvalue conversion. The attached patch adds the check when it is used 
for copy initialization.

There's some significant opportunity for refactoring with the static 
CheckForNullPointerDereference function in SemaExpr.cpp (not to be confused 
with the one I'm adding to SemaInit.cpp). Also, I've chosen different warning 
text since all cases where the existing warning fires get compiled to nothing, 
while cases where this warning fires may generate object code (creating "null 
references" usually).

Please review!

http://reviews.llvm.org/D19851

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaInit.cpp
  test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
  test/Parser/cxx-casting.cpp

Index: test/Parser/cxx-casting.cpp
===
--- test/Parser/cxx-casting.cpp
+++ test/Parser/cxx-casting.cpp
@@ -37,7 +37,7 @@
 // This was being incorrectly tentatively parsed.
 namespace test1 {
   template  class A {}; // expected-note 2{{here}}
-  void foo() { A(*(A*)0); }
+  void foo() { A(*(A*)0); } // expected-warning {{binding null 
pointer to reference has undefined behavior}}
 }
 
 typedef char* c;
Index: test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
===
--- test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
+++ test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
@@ -11,7 +11,7 @@
 
 template
 struct bogus_override_if_virtual : public T {
-  bogus_override_if_virtual() : T(*(T*)0) { }
+  bogus_override_if_virtual() : T(*(T*)0) { } // expected-warning {{binding 
null pointer to reference has undefined behavior}}
   int operator()() const;
 };
 
@@ -36,7 +36,7 @@
   lv(); // expected-error{{no matching function for call to object of type}}
   mlv(); // expected-error{{no matching function for call to object of type}}
 
-  bogus_override_if_virtual bogus;
+  bogus_override_if_virtual bogus; // expected-note{{in 
instantiation of member function 'bogus_override_if_virtual<(lambda}}
 }
 
 // Core issue 974: default arguments (8.3.6) may be specified in the
Index: lib/Sema/SemaInit.cpp
===
--- lib/Sema/SemaInit.cpp
+++ lib/Sema/SemaInit.cpp
@@ -3510,6 +3510,23 @@
   return CandidateSet.BestViableFunction(S, DeclLoc, Best);
 }
 
+static void CheckForNullPointerDereference(Sema &S, Expr *E) {
+  // Check to see if we are dereferencing a null pointer.  If so,
+  // and if not volatile-qualified, this is undefined behavior that the
+  // optimizer will delete, so warn about it.  People sometimes try to use this
+  // to get a deterministic trap and are surprised by clang's behavior.  This
+  // only handles the pattern "*null", which is a very syntactic check.
+  if (UnaryOperator *UO = dyn_cast(E->IgnoreParenCasts()))
+if (UO->getOpcode() == UO_Deref &&
+UO->getSubExpr()->IgnoreParenCasts()->
+  isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull) 
&&
+!UO->getType().isVolatileQualified()) {
+S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO,
+  S.PDiag(diag::warn_binding_null_to_reference)
+<< UO->getSubExpr()->getSourceRange());
+  }
+}
+
 /// \brief Attempt initialization by constructor (C++ [dcl.init]), which
 /// enumerates the constructors of the initialized entity and performs overload
 /// resolution to select the best.
@@ -3629,6 +3646,10 @@
 return;
   }
 
+  for (Expr *Arg : Args) {
+CheckForNullPointerDereference(S, Arg);
+  }
+
   // Add the constructor initialization step. Any cv-qualification conversion 
is
   // subsumed by the initialization.
   bool HadMultipleCandidates = (CandidateSet.size() > 1);
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -5359,6 +5359,8 @@
   InGroup>;
 def warn_indirection_through_null : Warning<
   "indirection of non-volatile null pointer will be deleted, not trap">, 
InGroup;
+def warn_binding_null_to_reference : Warning<
+  "binding null pointer to reference has undefined behavior">, 
InGroup;
 def note_indirection_through_null : Note<
   "consider using __builtin_trap() or qualifying pointer with 'volatile'">;
 def warn_pointer_indirection_from_incompatible_type : Warning<


Index: test/Parser/cxx-casting.cpp
===
--- test/Parser/cxx-casting.cpp
+++ test/Parser/cxx-casting.cpp
@@ -37,7 +37,7 @@
 // This was being incorrectly tentatively parsed.
 namespace test1 {
   temp

Re: [PATCH] D19851: Warn on binding reference to null in copy initialization

2016-05-04 Thread Nick Lewycky via cfe-commits
nicholas marked 2 inline comments as done.
nicholas added a comment.

Richard Smith gave me some review feedback in person, the diagnostic should not 
be generated when setting up the Steps for the initializer sequence, but 
instead when InitializerSequence::Perform is called. This appears to work 
correctly and also catches a few more cases.

I did not expand this to SK_BindReferenceToTemporary, please review this 
decision. It's also missing missing bit-field and vector element checks that 
SK_BindReference has.

Also, I'd appreciate comments on the factoring with 
CheckForNullPointerDereference which was copied+pasted from SemaExpr.cpp. 
Please review this issue too, I did not expect to land the patch the way it's 
currently written.



Comment at: test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp:39
@@ -38,3 +38,3 @@
 
-  bogus_override_if_virtual bogus;
+  bogus_override_if_virtual bogus; // expected-note{{in 
instantiation of member function 'bogus_override_if_virtual<(lambda}}
 }

aaron.ballman wrote:
> Missing `>` in the diagnostic text (I know it's not required, but it looks a 
> bit strange if that's the only part missing from the diagnostic text).
What follows lambda is the path to the file, then the closing )>. I'd rather 
not include that part. I could make it up with .* just to balance the parens, 
but I think that's not worth it.


http://reviews.llvm.org/D19851



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


Re: [PATCH] D19851: Warn on binding reference to null in copy initialization

2016-05-04 Thread Nick Lewycky via cfe-commits
nicholas updated this revision to Diff 56100.

http://reviews.llvm.org/D19851

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaInit.cpp
  test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
  test/Parser/cxx-casting.cpp
  test/SemaCXX/cstyle-cast.cpp
  test/SemaCXX/functional-cast.cpp
  test/SemaCXX/new-delete.cpp
  test/SemaCXX/static-cast.cpp

Index: test/SemaCXX/static-cast.cpp
===
--- test/SemaCXX/static-cast.cpp
+++ test/SemaCXX/static-cast.cpp
@@ -43,11 +43,11 @@
   (void)static_cast((int*)0);
   (void)static_cast((const int*)0);
   (void)static_cast((B*)0);
-  (void)static_cast(*((B*)0));
+  (void)static_cast(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((C1*)0);
-  (void)static_cast(*((C1*)0));
+  (void)static_cast(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((D*)0);
-  (void)static_cast(*((D*)0));
+  (void)static_cast(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((int A::*)0);
   (void)static_cast((void (A::*)())0);
 
Index: test/SemaCXX/new-delete.cpp
===
--- test/SemaCXX/new-delete.cpp
+++ test/SemaCXX/new-delete.cpp
@@ -444,11 +444,11 @@
 
   template
   void tfn() {
-new (*(PlacementArg*)0) T[1];
+new (*(PlacementArg*)0) T[1]; // expected-warning 2 {{binding null pointer to reference has undefined behavior}}
   }
 
   void fn() {
-tfn();
+tfn();  // expected-note {{in instantiation of function template specialization 'r150682::tfn' requested here}}
   }
 
 }
Index: test/SemaCXX/functional-cast.cpp
===
--- test/SemaCXX/functional-cast.cpp
+++ test/SemaCXX/functional-cast.cpp
@@ -126,14 +126,14 @@
   typedef A *Ap;
   (void)Ap((B*)0);
   typedef A &Ar;
-  (void)Ar(*((B*)0));
+  (void)Ar(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   typedef const B *cBp;
   (void)cBp((C1*)0);
   typedef B &Br;
-  (void)Br(*((C1*)0));
+  (void)Br(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)Ap((D*)0);
   typedef const A &cAr;
-  (void)cAr(*((D*)0));
+  (void)cAr(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   typedef int B::*Bmp;
   (void)Bmp((int A::*)0);
   typedef void (B::*Bmfp)();
Index: test/SemaCXX/cstyle-cast.cpp
===
--- test/SemaCXX/cstyle-cast.cpp
+++ test/SemaCXX/cstyle-cast.cpp
@@ -84,11 +84,11 @@
   (void)(void*)((int*)0);
   (void)(volatile const void*)((const int*)0);
   (void)(A*)((B*)0);
-  (void)(A&)(*((B*)0));
+  (void)(A&)(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(const B*)((C1*)0);
-  (void)(B&)(*((C1*)0));
+  (void)(B&)(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(A*)((D*)0);
-  (void)(const A&)(*((D*)0));
+  (void)(const A&)(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(int B::*)((int A::*)0);
   (void)(void (B::*)())((void (A::*)())0);
   (void)(A*)((E*)0); // C-style cast ignores access control
Index: test/Parser/cxx-casting.cpp
===
--- test/Parser/cxx-casting.cpp
+++ test/Parser/cxx-casting.cpp
@@ -37,7 +37,7 @@
 // This was being incorrectly tentatively parsed.
 namespace test1 {
   template  class A {}; // expected-note 2{{here}}
-  void foo() { A(*(A*)0); }
+  void foo() { A(*(A*)0); } // expected-warning {{binding null pointer to reference has undefined behavior}}
 }
 
 typedef char* c;
Index: test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
===
--- test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
+++ test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
@@ -11,7 +11,7 @@
 
 template
 struct bogus_override_if_virtual : public T {
-  bogus_override_if_virtual() : T(*(T*)0) { }
+  bogus_override_if_virtual() : T(*(T*)0) { } // expected-warning {{binding null pointer to reference has undefined behavior}}
   int operator()() const;
 };
 
@@ -36,7 +36,7 @@
   lv(); // expected-error{{no matching function for call to object of type}}
   mlv(); // expected-error{{no matching function for call to object of type}}
 
-  bogus_override_if_virtual bogus;
+  bogus_override_if_virtual bogus; // expected-note{{in instantiation of member function 'bogus_override_if_virtual<(lambda}}
 }
 
 // Core issue 974: default arguments (8.3.6) may be specified in the
Index: lib/Sema/SemaInit.cpp
===
--- lib/Sema/SemaInit.cpp
+++ 

Re: [PATCH] D19851: Warn on binding reference to null in copy initialization

2016-05-04 Thread Nick Lewycky via cfe-commits
nicholas marked 2 inline comments as done.


Comment at: lib/Sema/SemaInit.cpp:3514-3518
@@ +3513,7 @@
+static void CheckForNullPointerDereference(Sema &S, const Expr *E) {
+  // Check to see if we are dereferencing a null pointer.  If so,
+  // and if not volatile-qualified, this is undefined behavior that the
+  // optimizer will delete, so warn about it.  People sometimes try to use this
+  // to get a deterministic trap and are surprised by clang's behavior.  This
+  // only handles the pattern "*null", which is a very syntactic check.
+  if (const UnaryOperator *UO = dyn_cast(E->IgnoreParenCasts()))

rsmith wrote:
> This comment doesn't make sense for this case. Binding a reference to a 
> dereferenced null pointer isn't something that people would expect to trap. 
> But the idea is the same: we might delete people's code and they're probably 
> not expecting that.
We don't delete it, generally we "create a null reference" which is exactly 
what some programmers expect, when they think that references are just 
syntactically different pointers.


Comment at: lib/Sema/SemaInit.cpp:3519-3522
@@ +3518,6 @@
+  // only handles the pattern "*null", which is a very syntactic check.
+  if (const UnaryOperator *UO = dyn_cast(E->IgnoreParenCasts()))
+if (UO->getOpcode() == UO_Deref &&
+UO->getSubExpr()->IgnoreParenCasts()->
+  isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull) 
&&
+!UO->getType().isVolatileQualified()) {

rsmith wrote:
> It seems -- borderline -- worth factoring out these four lines between here 
> and SemaExpr. Maybe `isProvablyEmptyLvalue` or similar, if you feel inclined 
> to do so?
I'll pass. Initially I thought the two CheckForNullPointerDereference functions 
might be the same but for a diag::ID argument, but they're growing more and 
more different.

As for `isProvablyEmptyLvalue` we would still need to get the UO for the 
diagnostic anyways.


http://reviews.llvm.org/D19851



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


Re: [PATCH] D19851: Warn on binding reference to null in copy initialization

2016-05-04 Thread Nick Lewycky via cfe-commits
nicholas updated this revision to Diff 56235.
nicholas marked an inline comment as done.

http://reviews.llvm.org/D19851

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaInit.cpp
  test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
  test/Parser/cxx-casting.cpp
  test/SemaCXX/cstyle-cast.cpp
  test/SemaCXX/functional-cast.cpp
  test/SemaCXX/new-delete.cpp
  test/SemaCXX/static-cast.cpp

Index: test/SemaCXX/static-cast.cpp
===
--- test/SemaCXX/static-cast.cpp
+++ test/SemaCXX/static-cast.cpp
@@ -43,11 +43,11 @@
   (void)static_cast((int*)0);
   (void)static_cast((const int*)0);
   (void)static_cast((B*)0);
-  (void)static_cast(*((B*)0));
+  (void)static_cast(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((C1*)0);
-  (void)static_cast(*((C1*)0));
+  (void)static_cast(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((D*)0);
-  (void)static_cast(*((D*)0));
+  (void)static_cast(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((int A::*)0);
   (void)static_cast((void (A::*)())0);
 
Index: test/SemaCXX/new-delete.cpp
===
--- test/SemaCXX/new-delete.cpp
+++ test/SemaCXX/new-delete.cpp
@@ -444,11 +444,11 @@
 
   template
   void tfn() {
-new (*(PlacementArg*)0) T[1];
+new (*(PlacementArg*)0) T[1]; // expected-warning 2 {{binding null pointer to reference has undefined behavior}}
   }
 
   void fn() {
-tfn();
+tfn();  // expected-note {{in instantiation of function template specialization 'r150682::tfn' requested here}}
   }
 
 }
Index: test/SemaCXX/functional-cast.cpp
===
--- test/SemaCXX/functional-cast.cpp
+++ test/SemaCXX/functional-cast.cpp
@@ -126,14 +126,14 @@
   typedef A *Ap;
   (void)Ap((B*)0);
   typedef A &Ar;
-  (void)Ar(*((B*)0));
+  (void)Ar(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   typedef const B *cBp;
   (void)cBp((C1*)0);
   typedef B &Br;
-  (void)Br(*((C1*)0));
+  (void)Br(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)Ap((D*)0);
   typedef const A &cAr;
-  (void)cAr(*((D*)0));
+  (void)cAr(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   typedef int B::*Bmp;
   (void)Bmp((int A::*)0);
   typedef void (B::*Bmfp)();
Index: test/SemaCXX/cstyle-cast.cpp
===
--- test/SemaCXX/cstyle-cast.cpp
+++ test/SemaCXX/cstyle-cast.cpp
@@ -84,11 +84,11 @@
   (void)(void*)((int*)0);
   (void)(volatile const void*)((const int*)0);
   (void)(A*)((B*)0);
-  (void)(A&)(*((B*)0));
+  (void)(A&)(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(const B*)((C1*)0);
-  (void)(B&)(*((C1*)0));
+  (void)(B&)(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(A*)((D*)0);
-  (void)(const A&)(*((D*)0));
+  (void)(const A&)(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(int B::*)((int A::*)0);
   (void)(void (B::*)())((void (A::*)())0);
   (void)(A*)((E*)0); // C-style cast ignores access control
Index: test/Parser/cxx-casting.cpp
===
--- test/Parser/cxx-casting.cpp
+++ test/Parser/cxx-casting.cpp
@@ -37,7 +37,7 @@
 // This was being incorrectly tentatively parsed.
 namespace test1 {
   template  class A {}; // expected-note 2{{here}}
-  void foo() { A(*(A*)0); }
+  void foo() { A(*(A*)0); } // expected-warning {{binding null pointer to reference has undefined behavior}}
 }
 
 typedef char* c;
Index: test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
===
--- test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
+++ test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
@@ -11,7 +11,7 @@
 
 template
 struct bogus_override_if_virtual : public T {
-  bogus_override_if_virtual() : T(*(T*)0) { }
+  bogus_override_if_virtual() : T(*(T*)0) { } // expected-warning {{binding null pointer to reference has undefined behavior}}
   int operator()() const;
 };
 
@@ -36,7 +36,7 @@
   lv(); // expected-error{{no matching function for call to object of type}}
   mlv(); // expected-error{{no matching function for call to object of type}}
 
-  bogus_override_if_virtual bogus;
+  bogus_override_if_virtual bogus; // expected-note{{in instantiation of member function 'bogus_override_if_virtual<(lambda}}
 }
 
 // Core issue 974: default arguments (8.3.6) may be specified in the
Index: lib/Sema/SemaInit.cpp
===

Re: [PATCH] D19851: Warn on binding reference to null in copy initialization

2016-05-04 Thread Nick Lewycky via cfe-commits
nicholas updated this revision to Diff 56236.
nicholas added a comment.

(Whoops, forgot to generate diff with full context for phab.)


http://reviews.llvm.org/D19851

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaInit.cpp
  test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
  test/Parser/cxx-casting.cpp
  test/SemaCXX/cstyle-cast.cpp
  test/SemaCXX/functional-cast.cpp
  test/SemaCXX/new-delete.cpp
  test/SemaCXX/static-cast.cpp

Index: test/SemaCXX/static-cast.cpp
===
--- test/SemaCXX/static-cast.cpp
+++ test/SemaCXX/static-cast.cpp
@@ -43,11 +43,11 @@
   (void)static_cast((int*)0);
   (void)static_cast((const int*)0);
   (void)static_cast((B*)0);
-  (void)static_cast(*((B*)0));
+  (void)static_cast(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((C1*)0);
-  (void)static_cast(*((C1*)0));
+  (void)static_cast(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((D*)0);
-  (void)static_cast(*((D*)0));
+  (void)static_cast(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((int A::*)0);
   (void)static_cast((void (A::*)())0);
 
Index: test/SemaCXX/new-delete.cpp
===
--- test/SemaCXX/new-delete.cpp
+++ test/SemaCXX/new-delete.cpp
@@ -444,11 +444,11 @@
 
   template
   void tfn() {
-new (*(PlacementArg*)0) T[1];
+new (*(PlacementArg*)0) T[1]; // expected-warning 2 {{binding null pointer to reference has undefined behavior}}
   }
 
   void fn() {
-tfn();
+tfn();  // expected-note {{in instantiation of function template specialization 'r150682::tfn' requested here}}
   }
 
 }
Index: test/SemaCXX/functional-cast.cpp
===
--- test/SemaCXX/functional-cast.cpp
+++ test/SemaCXX/functional-cast.cpp
@@ -126,14 +126,14 @@
   typedef A *Ap;
   (void)Ap((B*)0);
   typedef A &Ar;
-  (void)Ar(*((B*)0));
+  (void)Ar(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   typedef const B *cBp;
   (void)cBp((C1*)0);
   typedef B &Br;
-  (void)Br(*((C1*)0));
+  (void)Br(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)Ap((D*)0);
   typedef const A &cAr;
-  (void)cAr(*((D*)0));
+  (void)cAr(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   typedef int B::*Bmp;
   (void)Bmp((int A::*)0);
   typedef void (B::*Bmfp)();
Index: test/SemaCXX/cstyle-cast.cpp
===
--- test/SemaCXX/cstyle-cast.cpp
+++ test/SemaCXX/cstyle-cast.cpp
@@ -84,11 +84,11 @@
   (void)(void*)((int*)0);
   (void)(volatile const void*)((const int*)0);
   (void)(A*)((B*)0);
-  (void)(A&)(*((B*)0));
+  (void)(A&)(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(const B*)((C1*)0);
-  (void)(B&)(*((C1*)0));
+  (void)(B&)(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(A*)((D*)0);
-  (void)(const A&)(*((D*)0));
+  (void)(const A&)(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(int B::*)((int A::*)0);
   (void)(void (B::*)())((void (A::*)())0);
   (void)(A*)((E*)0); // C-style cast ignores access control
Index: test/Parser/cxx-casting.cpp
===
--- test/Parser/cxx-casting.cpp
+++ test/Parser/cxx-casting.cpp
@@ -37,7 +37,7 @@
 // This was being incorrectly tentatively parsed.
 namespace test1 {
   template  class A {}; // expected-note 2{{here}}
-  void foo() { A(*(A*)0); }
+  void foo() { A(*(A*)0); } // expected-warning {{binding null pointer to reference has undefined behavior}}
 }
 
 typedef char* c;
Index: test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
===
--- test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
+++ test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
@@ -11,7 +11,7 @@
 
 template
 struct bogus_override_if_virtual : public T {
-  bogus_override_if_virtual() : T(*(T*)0) { }
+  bogus_override_if_virtual() : T(*(T*)0) { } // expected-warning {{binding null pointer to reference has undefined behavior}}
   int operator()() const;
 };
 
@@ -36,7 +36,7 @@
   lv(); // expected-error{{no matching function for call to object of type}}
   mlv(); // expected-error{{no matching function for call to object of type}}
 
-  bogus_override_if_virtual bogus;
+  bogus_override_if_virtual bogus; // expected-note{{in instantiation of member function 'bogus_override_if_virtual<(lambda}}
 }
 
 // Core issue 974: default arguments (8.3.6) may be specified in the
Index: lib/Sema/SemaInit.cpp

Re: [PATCH] D19851: Warn on binding reference to null in copy initialization

2016-05-08 Thread Nick Lewycky via cfe-commits
nicholas updated this revision to Diff 56526.
nicholas added a comment.

Unsure why, but the previous diff didn't have the 'volatile' check removed.


http://reviews.llvm.org/D19851

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaInit.cpp
  test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
  test/Parser/cxx-casting.cpp
  test/SemaCXX/cstyle-cast.cpp
  test/SemaCXX/functional-cast.cpp
  test/SemaCXX/new-delete.cpp
  test/SemaCXX/static-cast.cpp

Index: test/SemaCXX/static-cast.cpp
===
--- test/SemaCXX/static-cast.cpp
+++ test/SemaCXX/static-cast.cpp
@@ -43,11 +43,11 @@
   (void)static_cast((int*)0);
   (void)static_cast((const int*)0);
   (void)static_cast((B*)0);
-  (void)static_cast(*((B*)0));
+  (void)static_cast(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((C1*)0);
-  (void)static_cast(*((C1*)0));
+  (void)static_cast(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((D*)0);
-  (void)static_cast(*((D*)0));
+  (void)static_cast(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)static_cast((int A::*)0);
   (void)static_cast((void (A::*)())0);
 
Index: test/SemaCXX/new-delete.cpp
===
--- test/SemaCXX/new-delete.cpp
+++ test/SemaCXX/new-delete.cpp
@@ -444,11 +444,11 @@
 
   template
   void tfn() {
-new (*(PlacementArg*)0) T[1];
+new (*(PlacementArg*)0) T[1]; // expected-warning 2 {{binding null pointer to reference has undefined behavior}}
   }
 
   void fn() {
-tfn();
+tfn();  // expected-note {{in instantiation of function template specialization 'r150682::tfn' requested here}}
   }
 
 }
Index: test/SemaCXX/functional-cast.cpp
===
--- test/SemaCXX/functional-cast.cpp
+++ test/SemaCXX/functional-cast.cpp
@@ -126,14 +126,14 @@
   typedef A *Ap;
   (void)Ap((B*)0);
   typedef A &Ar;
-  (void)Ar(*((B*)0));
+  (void)Ar(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   typedef const B *cBp;
   (void)cBp((C1*)0);
   typedef B &Br;
-  (void)Br(*((C1*)0));
+  (void)Br(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)Ap((D*)0);
   typedef const A &cAr;
-  (void)cAr(*((D*)0));
+  (void)cAr(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   typedef int B::*Bmp;
   (void)Bmp((int A::*)0);
   typedef void (B::*Bmfp)();
Index: test/SemaCXX/cstyle-cast.cpp
===
--- test/SemaCXX/cstyle-cast.cpp
+++ test/SemaCXX/cstyle-cast.cpp
@@ -84,11 +84,11 @@
   (void)(void*)((int*)0);
   (void)(volatile const void*)((const int*)0);
   (void)(A*)((B*)0);
-  (void)(A&)(*((B*)0));
+  (void)(A&)(*((B*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(const B*)((C1*)0);
-  (void)(B&)(*((C1*)0));
+  (void)(B&)(*((C1*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(A*)((D*)0);
-  (void)(const A&)(*((D*)0));
+  (void)(const A&)(*((D*)0)); // expected-warning {{binding null pointer to reference has undefined behavior}}
   (void)(int B::*)((int A::*)0);
   (void)(void (B::*)())((void (A::*)())0);
   (void)(A*)((E*)0); // C-style cast ignores access control
Index: test/Parser/cxx-casting.cpp
===
--- test/Parser/cxx-casting.cpp
+++ test/Parser/cxx-casting.cpp
@@ -37,7 +37,7 @@
 // This was being incorrectly tentatively parsed.
 namespace test1 {
   template  class A {}; // expected-note 2{{here}}
-  void foo() { A(*(A*)0); }
+  void foo() { A(*(A*)0); } // expected-warning {{binding null pointer to reference has undefined behavior}}
 }
 
 typedef char* c;
Index: test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
===
--- test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
+++ test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
@@ -11,7 +11,7 @@
 
 template
 struct bogus_override_if_virtual : public T {
-  bogus_override_if_virtual() : T(*(T*)0) { }
+  bogus_override_if_virtual() : T(*(T*)0) { } // expected-warning {{binding null pointer to reference has undefined behavior}}
   int operator()() const;
 };
 
@@ -36,7 +36,7 @@
   lv(); // expected-error{{no matching function for call to object of type}}
   mlv(); // expected-error{{no matching function for call to object of type}}
 
-  bogus_override_if_virtual bogus;
+  bogus_override_if_virtual bogus; // expected-note{{in instantiation of member function 'bogus_override_if_virtual<(lambda}}
 }
 
 // Core issue 974: default arguments (8.3.6) may be specified in the
Index: lib/Sema/SemaIni

r269572 - Warn when a reference is bound to an empty l-value (dereferenced null pointer).

2016-05-14 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Sat May 14 12:44:14 2016
New Revision: 269572

URL: http://llvm.org/viewvc/llvm-project?rev=269572&view=rev
Log:
Warn when a reference is bound to an empty l-value (dereferenced null pointer).

Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
cfe/trunk/test/Parser/cxx-casting.cpp
cfe/trunk/test/SemaCXX/cstyle-cast.cpp
cfe/trunk/test/SemaCXX/functional-cast.cpp
cfe/trunk/test/SemaCXX/new-delete.cpp
cfe/trunk/test/SemaCXX/static-cast.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=269572&r1=269571&r2=269572&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Sat May 14 12:44:14 
2016
@@ -5371,7 +5371,11 @@ def ext_typecheck_indirection_through_vo
   "ISO C++ does not allow indirection on operand of type %0">,
   InGroup>;
 def warn_indirection_through_null : Warning<
-  "indirection of non-volatile null pointer will be deleted, not trap">, 
InGroup;
+  "indirection of non-volatile null pointer will be deleted, not trap">,
+  InGroup;
+def warn_binding_null_to_reference : Warning<
+  "binding dereferenced null pointer to reference has undefined behavior">,
+  InGroup;
 def note_indirection_through_null : Note<
   "consider using __builtin_trap() or qualifying pointer with 'volatile'">;
 def warn_pointer_indirection_from_incompatible_type : Warning<

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=269572&r1=269571&r2=269572&view=diff
==
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Sat May 14 12:44:14 2016
@@ -6168,6 +6168,20 @@ static void CheckMoveOnConstruction(Sema
   << FixItHint::CreateRemoval(SourceRange(RParen, RParen));
 }
 
+static void CheckForNullPointerDereference(Sema &S, const Expr *E) {
+  // Check to see if we are dereferencing a null pointer.  If so, this is
+  // undefined behavior, so warn about it.  This only handles the pattern
+  // "*null", which is a very syntactic check.
+  if (const UnaryOperator *UO = dyn_cast(E->IgnoreParenCasts()))
+if (UO->getOpcode() == UO_Deref &&
+UO->getSubExpr()->IgnoreParenCasts()->
+isNullPointerConstant(S.Context, Expr::NPC_ValueDependentIsNotNull)) {
+S.DiagRuntimeBehavior(UO->getOperatorLoc(), UO,
+  S.PDiag(diag::warn_binding_null_to_reference)
+<< UO->getSubExpr()->getSourceRange());
+  }
+}
+
 ExprResult
 InitializationSequence::Perform(Sema &S,
 const InitializedEntity &Entity,
@@ -6420,6 +6434,7 @@ InitializationSequence::Perform(Sema &S,
   /*IsInitializerList=*/false,
   ExtendingEntity->getDecl());
 
+  CheckForNullPointerDereference(S, CurInit.get());
   break;
 
 case SK_BindReferenceToTemporary: {

Modified: cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp?rev=269572&r1=269571&r2=269572&view=diff
==
--- cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.prim/expr.prim.lambda/p5.cpp Sat May 14 
12:44:14 2016
@@ -11,7 +11,7 @@ void test_attributes() {
 
 template
 struct bogus_override_if_virtual : public T {
-  bogus_override_if_virtual() : T(*(T*)0) { }
+  bogus_override_if_virtual() : T(*(T*)0) { } // expected-warning {{binding 
dereferenced null pointer to reference has undefined behavior}}
   int operator()() const;
 };
 
@@ -36,7 +36,7 @@ void test_quals() {
   lv(); // expected-error{{no matching function for call to object of type}}
   mlv(); // expected-error{{no matching function for call to object of type}}
 
-  bogus_override_if_virtual bogus;
+  bogus_override_if_virtual bogus; // expected-note{{in 
instantiation of member function 'bogus_override_if_virtual<(lambda}}
 }
 
 // Core issue 974: default arguments (8.3.6) may be specified in the

Modified: cfe/trunk/test/Parser/cxx-casting.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx-casting.cpp?rev=269572&r1=269571&r2=269572&view=diff
==
--- cfe/trunk/test/Parser/cxx-casting.cpp (original)
+++ cfe/trunk/test/Parser/cxx-casting.cpp Sat May 14 12:44:14 2016
@@ -37,7 +37,7 @@ char postfix_expr_test()
 // This was being incorrectly tentatively parsed.
 namesp

Re: [PATCH] D19851: Warn on binding reference to null in copy initialization

2016-05-14 Thread Nick Lewycky via cfe-commits
nicholas closed this revision.
nicholas added a comment.

Closed by r269572.


http://reviews.llvm.org/D19851



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


r269625 - Make this SourceLocation getter const LLVM_READONLY like others in the same file.

2016-05-15 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Sun May 15 21:46:07 2016
New Revision: 269625

URL: http://llvm.org/viewvc/llvm-project?rev=269625&view=rev
Log:
Make this SourceLocation getter const LLVM_READONLY like others in the same 
file.

Modified:
cfe/trunk/include/clang/AST/StmtObjC.h

Modified: cfe/trunk/include/clang/AST/StmtObjC.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/StmtObjC.h?rev=269625&r1=269624&r2=269625&view=diff
==
--- cfe/trunk/include/clang/AST/StmtObjC.h (original)
+++ cfe/trunk/include/clang/AST/StmtObjC.h Sun May 15 21:46:07 2016
@@ -326,7 +326,7 @@ public:
   Expr *getThrowExpr() { return reinterpret_cast(Throw); }
   void setThrowExpr(Stmt *S) { Throw = S; }
 
-  SourceLocation getThrowLoc() { return AtThrowLoc; }
+  SourceLocation getThrowLoc() const LLVM_READONLY { return AtThrowLoc; }
   void setThrowLoc(SourceLocation Loc) { AtThrowLoc = Loc; }
 
   SourceLocation getLocStart() const LLVM_READONLY { return AtThrowLoc; }


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


Re: r269572 - Warn when a reference is bound to an empty l-value (dereferenced null pointer).

2016-05-16 Thread Nick Lewycky via cfe-commits

Hans Wennborg wrote:

On Sat, May 14, 2016 at 10:44 AM, Nick Lewycky via cfe-commits
  wrote:


Author: nicholas
Date: Sat May 14 12:44:14 2016
New Revision: 269572

URL: http://llvm.org/viewvc/llvm-project?rev=269572&view=rev
Log:
Warn when a reference is bound to an empty l-value (dereferenced null pointer).


Could this be made to handle return values too? The warning fired on
some code in pdfium, and nearby I found this:

   TYPE&  ElementAt(int nIndex) {
 if (nIndex<  0 || nIndex>= m_nSize) {
   return *(TYPE*)NULL;<-- Ooops
 }
 return ((TYPE*)m_pData)[nIndex];
   }

where the warning doesn't fire.


That looks like a bug, we should already catch that case:

  int &test1() {
return *(int*)nullptr;
  }
  struct TYPE {};
  TYPE &test2() {
return *(TYPE*)nullptr;
  }

  clang ref.cc -std=c++11
  ref.cc:2:10: warning: binding dereferenced null pointer to reference has
undefined behavior [-Wnull-dereference]
return *(int*)nullptr;
   ^~
  ref.cc:6:10: warning: binding dereferenced null pointer to reference has
  undefined behavior [-Wnull-dereference]
return *(TYPE*)nullptr;
   ^~~
  2 warnings generated.

Could you produce a testcase for it?

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


[PATCH] D21352: Add a "declared 'nonnull' here" note to warnings where an expression is checked against null.

2016-06-14 Thread Nick Lewycky via cfe-commits
nlewycky created this revision.
nlewycky added a subscriber: cfe-commits.

Point to the relevant 'nonnull' or 'returns_nonnull' attribute when complaining 
about 'a == 0' or 'f() == 0' expressions.

http://reviews.llvm.org/D21352

Files:
  include/clang/Basic/DiagnosticSemaKinds.td
  lib/Sema/SemaChecking.cpp
  test/Sema/nonnull.c

Index: test/Sema/nonnull.c
===
--- test/Sema/nonnull.c
+++ test/Sema/nonnull.c
@@ -86,7 +86,7 @@
 
 // rdar://18712242
 #define NULL (void*)0
-__attribute__((__nonnull__))
+__attribute__((__nonnull__))  // expected-note 2{{declared 'nonnull' here}}
 int evil_nonnull_func(int* pointer, void * pv)
 {
if (pointer == NULL) {  // expected-warning {{comparison of nonnull parameter 'pointer' equal to a null pointer is 'false' on first encounter}}
@@ -105,7 +105,7 @@
 }
 
 void set_param_to_null(int**);
-int another_evil_nonnull_func(int* pointer, char ch, void * pv) __attribute__((nonnull(1, 3)));
+int another_evil_nonnull_func(int* pointer, char ch, void * pv) __attribute__((nonnull(1, 3)));  // expected-note 2{{declared 'nonnull' here}}
 int another_evil_nonnull_func(int* pointer, char ch, void * pv) {
if (pointer == NULL) { // expected-warning {{comparison of nonnull parameter 'pointer' equal to a null pointer is 'false' on first encounter}}
  return 0;
@@ -127,7 +127,7 @@
 extern void FEE();
 
 extern void *pv;
-__attribute__((__nonnull__))
+__attribute__((__nonnull__))  // expected-note {{declared 'nonnull' here}}
 void yet_another_evil_nonnull_func(int* pointer)
 {
  while (pv) {
@@ -141,7 +141,7 @@
  }
 }
 
-void pr21668_1(__attribute__((nonnull)) const char *p, const char *s) {
+void pr21668_1(__attribute__((nonnull)) const char *p, const char *s) { // expected-note {{declared 'nonnull' here}}
   if (p) // expected-warning {{nonnull parameter 'p' will evaluate to 'true' on first encounter}}
 ;
   if (s) // No warning
@@ -154,7 +154,7 @@
 ;
 }
 
-__attribute__((returns_nonnull)) void *returns_nonnull_whee();
+__attribute__((returns_nonnull)) void *returns_nonnull_whee();  // expected-note 6{{declared 'returns_nonnull' here}}
 
 void returns_nonnull_warning_tests() {
   if (returns_nonnull_whee() == NULL) {} // expected-warning {{comparison of nonnull function call 'returns_nonnull_whee()' equal to a null pointer is 'false' on first encounter}}
Index: lib/Sema/SemaChecking.cpp
===
--- lib/Sema/SemaChecking.cpp
+++ lib/Sema/SemaChecking.cpp
@@ -8460,21 +8460,23 @@
 }
   }
 
-  auto ComplainAboutNonnullParamOrCall = [&](bool IsParam) {
+  auto ComplainAboutNonnullParamOrCall = [&](const Attr *NonnullAttr) {
+bool IsParam = isa(NonnullAttr);
 std::string Str;
 llvm::raw_string_ostream S(Str);
 E->printPretty(S, nullptr, getPrintingPolicy());
 unsigned DiagID = IsCompare ? diag::warn_nonnull_expr_compare
 : diag::warn_cast_nonnull_to_bool;
 Diag(E->getExprLoc(), DiagID) << IsParam << S.str()
   << E->getSourceRange() << Range << IsEqual;
+Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
   };
 
   // If we have a CallExpr that is tagged with returns_nonnull, we can complain.
   if (auto *Call = dyn_cast(E->IgnoreParenImpCasts())) {
 if (auto *Callee = Call->getDirectCallee()) {
-  if (Callee->hasAttr()) {
-ComplainAboutNonnullParamOrCall(false);
+  if (const Attr *A = Callee->getAttr()) {
+ComplainAboutNonnullParamOrCall(A);
 return;
   }
 }
@@ -8496,8 +8498,8 @@
   if (const auto* PV = dyn_cast(D)) {
 if (getCurFunction() &&
 !getCurFunction()->ModifiedNonNullParams.count(PV)) {
-  if (PV->hasAttr()) {
-ComplainAboutNonnullParamOrCall(true);
+  if (const Attr *A = PV->getAttr()) {
+ComplainAboutNonnullParamOrCall(A);
 return;
   }
 
@@ -8508,13 +8510,13 @@
 
 for (const auto *NonNull : FD->specific_attrs()) {
   if (!NonNull->args_size()) {
-  ComplainAboutNonnullParamOrCall(true);
+  ComplainAboutNonnullParamOrCall(NonNull);
   return;
   }
 
   for (unsigned ArgNo : NonNull->args()) {
 if (ArgNo == ParamNo) {
-  ComplainAboutNonnullParamOrCall(true);
+  ComplainAboutNonnullParamOrCall(NonNull);
   return;
 }
   }
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -2933,6 +2933,8 @@
 def warn_attribute_nonnull_parm_no_args : Warning<
   "'nonnull' attribute when used on parameters takes no arguments">,
   InGroup;
+def note_declared_nonnull : Note<
+  "declared %select{'returns_nonnull'|'nonnull'}0 here">;
 def warn_attribute_sentinel_named_arguments : Warning<

r272755 - Add a "declared 'nonnull' here" note to warnings where an expression is checked against null.

2016-06-14 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Wed Jun 15 00:18:39 2016
New Revision: 272755

URL: http://llvm.org/viewvc/llvm-project?rev=272755&view=rev
Log:
Add a "declared 'nonnull' here" note to warnings where an expression is checked 
against null.

Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/nonnull.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=272755&r1=272754&r2=272755&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jun 15 00:18:39 
2016
@@ -2933,6 +2933,8 @@ def warn_attribute_nonnull_no_pointers :
 def warn_attribute_nonnull_parm_no_args : Warning<
   "'nonnull' attribute when used on parameters takes no arguments">,
   InGroup;
+def note_declared_nonnull : Note<
+  "declared %select{'returns_nonnull'|'nonnull'}0 here">;
 def warn_attribute_sentinel_named_arguments : Warning<
   "'sentinel' attribute requires named arguments">,
   InGroup;

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=272755&r1=272754&r2=272755&view=diff
==
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed Jun 15 00:18:39 2016
@@ -8460,7 +8460,8 @@ void Sema::DiagnoseAlwaysNonNullPointer(
 }
   }
 
-  auto ComplainAboutNonnullParamOrCall = [&](bool IsParam) {
+  auto ComplainAboutNonnullParamOrCall = [&](const Attr *NonnullAttr) {
+bool IsParam = isa(NonnullAttr);
 std::string Str;
 llvm::raw_string_ostream S(Str);
 E->printPretty(S, nullptr, getPrintingPolicy());
@@ -8468,13 +8469,14 @@ void Sema::DiagnoseAlwaysNonNullPointer(
 : diag::warn_cast_nonnull_to_bool;
 Diag(E->getExprLoc(), DiagID) << IsParam << S.str()
   << E->getSourceRange() << Range << IsEqual;
+Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
   };
 
   // If we have a CallExpr that is tagged with returns_nonnull, we can 
complain.
   if (auto *Call = dyn_cast(E->IgnoreParenImpCasts())) {
 if (auto *Callee = Call->getDirectCallee()) {
-  if (Callee->hasAttr()) {
-ComplainAboutNonnullParamOrCall(false);
+  if (const Attr *A = Callee->getAttr()) {
+ComplainAboutNonnullParamOrCall(A);
 return;
   }
 }
@@ -8496,8 +8498,8 @@ void Sema::DiagnoseAlwaysNonNullPointer(
   if (const auto* PV = dyn_cast(D)) {
 if (getCurFunction() &&
 !getCurFunction()->ModifiedNonNullParams.count(PV)) {
-  if (PV->hasAttr()) {
-ComplainAboutNonnullParamOrCall(true);
+  if (const Attr *A = PV->getAttr()) {
+ComplainAboutNonnullParamOrCall(A);
 return;
   }
 
@@ -8508,13 +8510,13 @@ void Sema::DiagnoseAlwaysNonNullPointer(
 
 for (const auto *NonNull : FD->specific_attrs()) {
   if (!NonNull->args_size()) {
-  ComplainAboutNonnullParamOrCall(true);
+  ComplainAboutNonnullParamOrCall(NonNull);
   return;
   }
 
   for (unsigned ArgNo : NonNull->args()) {
 if (ArgNo == ParamNo) {
-  ComplainAboutNonnullParamOrCall(true);
+  ComplainAboutNonnullParamOrCall(NonNull);
   return;
 }
   }

Modified: cfe/trunk/test/Sema/nonnull.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/nonnull.c?rev=272755&r1=272754&r2=272755&view=diff
==
--- cfe/trunk/test/Sema/nonnull.c (original)
+++ cfe/trunk/test/Sema/nonnull.c Wed Jun 15 00:18:39 2016
@@ -86,7 +86,7 @@ void redecl_test(void *p) {
 
 // rdar://18712242
 #define NULL (void*)0
-__attribute__((__nonnull__))
+__attribute__((__nonnull__))  // expected-note 2{{declared 'nonnull' here}}
 int evil_nonnull_func(int* pointer, void * pv)
 {
if (pointer == NULL) {  // expected-warning {{comparison of nonnull 
parameter 'pointer' equal to a null pointer is 'false' on first encounter}}
@@ -105,7 +105,7 @@ int evil_nonnull_func(int* pointer, void
 }
 
 void set_param_to_null(int**);
-int another_evil_nonnull_func(int* pointer, char ch, void * pv) 
__attribute__((nonnull(1, 3)));
+int another_evil_nonnull_func(int* pointer, char ch, void * pv) 
__attribute__((nonnull(1, 3)));  // expected-note 2{{declared 'nonnull' here}}
 int another_evil_nonnull_func(int* pointer, char ch, void * pv) {
if (pointer == NULL) { // expected-warning {{comparison of nonnull 
parameter 'pointer' equal to a null pointer is 'false' on first encounter}}
  return 0;
@@ -127,7 +127,7 @@ extern void FOO();
 extern void FEE();
 
 extern vo

Re: [PATCH] D21352: Add a "declared 'nonnull' here" note to warnings where an expression is checked against null.

2016-06-14 Thread Nick Lewycky via cfe-commits
nlewycky closed this revision.
nlewycky added a comment.

Closed by r272755.


http://reviews.llvm.org/D21352



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


Re: [PATCH] D15861: Support fully-qualified names for all QualTypes

2016-01-04 Thread Nick Lewycky via cfe-commits
nlewycky added a subscriber: nlewycky.
nlewycky added a comment.

(I'm not doing a full review, I just happened to notice a couple things when 
skimming.)



Comment at: lib/Tooling/Core/QualTypeNames.cpp:250
@@ +249,3 @@
+// There are probably other cases ...
+if (const TagType *TagDeclType = llvm::dyn_cast_or_null(TypePtr))
+  Decl = TagDeclType->getDecl();

s/dyn_cast_or_null/dyn_cast/

You've already checked !TypePtr above, so it can't be null here.


Comment at: lib/Tooling/Core/QualTypeNames.cpp:306
@@ +305,3 @@
+  // In case of myType& we need to strip the reference first, fully
+  // qualifiy and attach the reference once again.
+  if (llvm::isa(QT.getTypePtr())) {

s/qualifiy/qualify/


http://reviews.llvm.org/D15861



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


Re: r255371 - Error on redeclaring with a conflicting asm label and on redeclaring with an asm label after the first ODR-use. Detects problems like the one in PR22830 where gcc and clang both compiled

2016-01-04 Thread Nick Lewycky via cfe-commits

On 01/04/2016 01:40 PM, Kostya Serebryany wrote:



On Thu, Dec 17, 2015 at 5:03 PM, Richard Smith mailto:rich...@metafoo.co.uk>> wrote:

On Thu, Dec 17, 2015 at 3:59 PM, Nick Lewycky via cfe-commits
mailto:cfe-commits@lists.llvm.org>> wrote:

On 12/17/2015 10:47 AM, Kostya Serebryany wrote:

I am now observing this error message when building glibc
with clang
(from trunk):
../include/string.h:101:28: error: cannot apply asm label to
function
after its first use
libc_hidden_builtin_proto (memcpy)
(many more instances)


Do you think this is a bug in glibc code, or the error
message could be
more relaxed?


Could you email me a .i copy of a failing build? That will help
me decide whether it's a bug in the error or in glibc.


[sorry for delay,]
here is the preprocessed source file from glibc:
% clang  ~/tmp/a.i 2>&1 | grep error:
../include/sys/stat.h:16:28: error: cannot apply asm label to function
after its first use
../include/sys/stat.h:17:30: error: cannot apply asm label to function
after its first use
../include/sys/stat.h:18:28: error: cannot apply asm label to function
after its first use
../include/sys/stat.h:19:30: error: cannot apply asm label to function
after its first use
...


Also PR22830 comment 1 seems relevant here.


Probably, but since this is a very recent regression in clang I thought
I should report it.


This looks like it's WAI:

3783extern int __fxstat (int __ver, int __fildes, struct stat 
*__stat_buf)

3784 __attribute__ ((__nothrow__ )) ;
...
3827extern __inline int
3828__attribute__ ((__nothrow__ )) fstat (int __fd, struct stat 
*__statbuf)

3829{
3830  return __fxstat (1, __fd, __statbuf);
3831}
...
3910extern __typeof (__fxstat) __fxstat __asm__ ("" "__GI___fxstat") 
__attribute__ ((visibility ("hidden")));


This is exactly the situation where GCC and Clang will emit a different 
.o file.


Nick


        On Fri, Dec 11, 2015 at 1:28 PM, Nick Lewycky via cfe-commits
mailto:cfe-commits@lists.llvm.org>
<mailto:cfe-commits@lists.llvm.org
<mailto:cfe-commits@lists.llvm.org>>> wrote:

 Author: nicholas
 Date: Fri Dec 11 15:28:55 2015
 New Revision: 255371

 URL:
http://llvm.org/viewvc/llvm-project?rev=255371&view=rev
 Log:
 Error on redeclaring with a conflicting asm label and
on redeclaring
 with an asm label after the first ODR-use. Detects
problems like the
 one in PR22830 where gcc and clang both compiled the
file but with
 different behaviour.

 Added:
  cfe/trunk/test/Sema/asm-label.c
 Modified:
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/lib/Sema/SemaDecl.cpp

 Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
 URL:

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


==
 ---
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
 +++
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Dec 11
 15:28:55 2015
 @@ -4259,6 +4259,9 @@ def err_tag_definition_of_typedef
: Erro
   def err_conflicting_types : Error<"conflicting types
for %0">;
   def err_different_pass_object_size_params : Error<
 "conflicting pass_object_size attributes on
parameters">;
 +def err_late_asm_label_name : Error<
 +  "cannot apply asm label to
%select{variable|function}0 after its
 first use">;
 +def err_different_asm_label : Error<"conflicting asm
label">;
   def err_nested_redefinition : Error<"nested
redefinition of %0">;
   def err_use_with_wrong_tag : Error<
 "use of %0 with tag type that does not match
previous declaration">;

 Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
 URL:

http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=255371&r1=255370&r2=255371&view=diff


===

Re: [PATCH] D16171: Warning on redeclaring with a conflicting asm label

2016-01-14 Thread Nick Lewycky via cfe-commits

Weiming Zhao wrote:

weimingz created this revision.
weimingz added a reviewer: nicholas.
weimingz added a subscriber: cfe-commits.

r255371 errors on redeclaring with a conflicting asm label.
This patch changes errors to warnings to prevent breaking existing codes.


Can you include a testcase where the warning is issued but clang and gcc 
emit the same .o file?




http://reviews.llvm.org/D16171

Files:
   include/clang/Basic/DiagnosticSemaKinds.td
   lib/Sema/SemaDecl.cpp
   test/Sema/asm-label.c

Index: test/Sema/asm-label.c
===
--- test/Sema/asm-label.c
+++ test/Sema/asm-label.c
@@ -7,21 +7,21 @@
  void f() {
g();
  }
-void g() __asm__("gold");  // expected-error{{cannot apply asm label to 
function after its first use}}
+void g() __asm__("gold");  // expected-warning{{cannot apply asm label to 
function after its first use}}

  void h() __asm__("hose");  // expected-note{{previous declaration is here}}
-void h() __asm__("hair");  // expected-error{{conflicting asm label}}
+void h() __asm__("hair");  // expected-warning{{conflicting asm label}}

  int x;
  int x __asm__("xenon");
  int y;

  int test() { return y; }

-int y __asm__("yacht");  // expected-error{{cannot apply asm label to variable 
after its first use}}
+int y __asm__("yacht");  // expected-warning{{cannot apply asm label to 
variable after its first use}}

  int z __asm__("zebra");  // expected-note{{previous declaration is here}}
-int z __asm__("zooms");  // expected-error{{conflicting asm label}}
+int z __asm__("zooms");  // expected-warning{{conflicting asm label}}


  // No diagnostics on the following.
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2385,13 +2385,13 @@
  if (AsmLabelAttr *OldA = Old->getAttr()) {
if (OldA->getLabel() != NewA->getLabel()) {
  // This redeclaration changes __asm__ label.
-Diag(New->getLocation(), diag::err_different_asm_label);
+Diag(New->getLocation(), diag::warn_different_asm_label);
  Diag(OldA->getLocation(), diag::note_previous_declaration);
}
  } else if (Old->isUsed()) {
// This redeclaration adds an __asm__ label to a declaration that has
// already been ODR-used.
-  Diag(New->getLocation(), diag::err_late_asm_label_name)
+  Diag(New->getLocation(), diag::warn_late_asm_label_name)
  <<  isa(Old)<<  
New->getAttr()->getRange();
  }
}
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td
+++ include/clang/Basic/DiagnosticSemaKinds.td
@@ -4266,9 +4266,11 @@
  def err_conflicting_types : Error<"conflicting types for %0">;
  def err_different_pass_object_size_params : Error<
"conflicting pass_object_size attributes on parameters">;
-def err_late_asm_label_name : Error<
-  "cannot apply asm label to %select{variable|function}0 after its first use">;
-def err_different_asm_label : Error<"conflicting asm label">;
+def warn_late_asm_label_name : Warning<
+  "cannot apply asm label to %select{variable|function}0 after its first use">,
+  InGroup;
+def warn_different_asm_label : Warning<"conflicting asm label">,
+  InGroup;
  def err_nested_redefinition : Error<"nested redefinition of %0">;
  def err_use_with_wrong_tag : Error<
"use of %0 with tag type that does not match previous declaration">;




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


Re: [PATCH] D16171: Warning on redeclaring with a conflicting asm label

2016-01-14 Thread Nick Lewycky via cfe-commits
nicholas added a subscriber: nicholas.
nicholas added a comment.

Weiming Zhao wrote:

> weimingz created this revision.

>  weimingz added a reviewer: nicholas.

>  weimingz added a subscriber: cfe-commits.

> 

> r255371 errors on redeclaring with a conflicting asm label.

>  This patch changes errors to warnings to prevent breaking existing codes.


Can you include a testcase where the warning is issued but clang and gcc 
emit the same .o file?

> http://reviews.llvm.org/D16171

> 

> Files:

> 

>   include/clang/Basic/DiagnosticSemaKinds.td

>   lib/Sema/SemaDecl.cpp

>   test/Sema/asm-label.c

> 

> Index: test/Sema/asm-label.c

>  ===

> 

> - test/Sema/asm-label.c +++ test/Sema/asm-label.c @@ -7,21 +7,21 @@ void f() 
> { g(); } -void g() __asm__("gold");  // expected-error{{cannot apply asm 
> label to function after its first use}} +void g() __asm__("gold");  // 
> expected-warning{{cannot apply asm label to function after its first use}}

> 

>   void h() __asm__("hose");  // expected-note{{previous declaration is here}} 
> -void h() __asm__("hair");  // expected-error{{conflicting asm label}} +void 
> h() __asm__("hair");  // expected-warning{{conflicting asm label}}

> 

>   int x; int x __asm__("xenon"); int y;

> 

>   int test() { return y; }

> 

>   -int y __asm__("yacht");  // expected-error{{cannot apply asm label to 
> variable after its first use}} +int y __asm__("yacht");  // 
> expected-warning{{cannot apply asm label to variable after its first use}}

> 

>   int z __asm__("zebra");  // expected-note{{previous declaration is here}} 
> -int z __asm__("zooms");  // expected-error{{conflicting asm label}} +int z 
> __asm__("zooms");  // expected-warning{{conflicting asm label}}

> 

> 

> 

>   // No diagnostics on the following.

> 

> Index: lib/Sema/SemaDecl.cpp

>  ===

> 

>   - lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -2385,13 +2385,13 @@ 
> if (AsmLabelAttr *OldA = Old->getAttr()) { if (OldA->getLabel() 
> != NewA->getLabel()) { // This redeclaration changes __asm__ label.

> - Diag(New->getLocation(), diag::err_different_asm_label); +
> Diag(New->getLocation(), diag::warn_different_asm_label); 
> Diag(OldA->getLocation(), diag::note_previous_declaration); } } else if 
> (Old->isUsed()) { // This redeclaration adds an __asm__ label to a 
> declaration that has // already been ODR-used.

> - Diag(New->getLocation(), diag::err_late_asm_label_name) +  
> Diag(New->getLocation(), diag::warn_late_asm_label_name) <<  
> isa(Old)<<  New->getAttr()->getRange(); } } 
> Index: include/clang/Basic/DiagnosticSemaKinds.td 
> ===

>   - include/clang/Basic/DiagnosticSemaKinds.td +++ 
> include/clang/Basic/DiagnosticSemaKinds.td @@ -4266,9 +4266,11 @@ def 
> err_conflicting_types : Error<"conflicting types for %0">; def 
> err_different_pass_object_size_params : Error< "conflicting pass_object_size 
> attributes on parameters">; -def err_late_asm_label_name : Error<

> - "cannot apply asm label to %select{variable|function}0 after its first 
> use">; -def err_different_asm_label : Error<"conflicting asm label">; +def 
> warn_late_asm_label_name : Warning< +  "cannot apply asm label to 
> %select{variable|function}0 after its first use">, +  
> InGroup; +def warn_different_asm_label : Warning<"conflicting 
> asm label">, +  InGroup; def err_nested_redefinition : 
> Error<"nested redefinition of %0">; def err_use_with_wrong_tag : Error< "use 
> of %0 with tag type that does not match previous declaration">;



http://reviews.llvm.org/D16171



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


Re: [PATCH] D16171: Warning on redeclaring with a conflicting asm label

2016-01-14 Thread Nick Lewycky via cfe-commits
On 14 January 2016 at 10:38, Weiming Zhao via cfe-commits <
cfe-commits@lists.llvm.org> wrote:

> weimingz added a comment.
>
> Hi Nick,
>
> Below is a reduced code:
> t.c:
>
>   static long double acoshl (long double __x) __asm__ ("" "acosh") ;  //
> this is from /arm-linux-gnueabi/libc/usr/include/bits/mathcalls.h
>   extern long double acoshl (long double) __asm__ ("" "__acoshl_finite") ;
> // this is from existing code
>
> GCC gives warning like:
> /tmp/t.c:2:1: warning: asm declaration ignored due to conflict with
> previous rename [-Wpragmas]
>  extern long double acoshl (long double) __asm__ ("" "__acoshl_finite") ;
>

That's the same case as in this testcase:

  void foo() __asm__("one");
  void foo() __asm__("two");
  void test() { foo(); }

GCC emits a call to 'one' while Clang emits a call to 'two'. This is a real
bug. Please don't downgrade this to a warning.

As an alternative, I would accept a patch which changes how clang generates
code so that it also produces a call to 'one', with a warning. It looks
like what we need to do is drop subsequent asm label declarations on
functions that already have one.

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


Re: [PATCH] D16171: Warning on redeclaring with a conflicting asm label

2016-01-14 Thread Nick Lewycky via cfe-commits
On 14 January 2016 at 15:05, Zhao, Weiming  wrote:

> I agree what you said about different code generated with clang and GCC
> generates. In this case, we should throw an error (err_late_asm_label).
>
> But in this example, there is no use of the function. They are just
> redundant declarations and there is no actual code generated.
> So I suggest we just give warnings for this case. Otherwise, it will break
> existing code like some SPEC benchmarks.
>
> Please review my 2nd patch.
>

I think your second patch checks whether it's used at the time of the
redeclaration, which is too early. It may be used between there and the end
of the program. I expect it not to warn but not error on the testcase I
posted in my previous email?

To fix, you'd need to store a list of different-asm-label declarations in
Sema, check it each time something is ODR-used (see the
Sema::Mark<...>Referenced family of calls) to emit the error and remove it
from the list. Also, when emitting a PCH or a Module, you need to serialize
and deserialize this list.

Nick

Weiming
>
>
> On 1/14/2016 2:28 PM, Nick Lewycky wrote:
>
> On 14 January 2016 at 10:38, Weiming Zhao via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> weimingz added a comment.
>>
>> Hi Nick,
>>
>> Below is a reduced code:
>> t.c:
>>
>>   static long double acoshl (long double __x) __asm__ ("" "acosh") ;  //
>> this is from /arm-linux-gnueabi/libc/usr/include/bits/mathcalls.h
>>   extern long double acoshl (long double) __asm__ ("" "__acoshl_finite")
>> ; // this is from existing code
>>
>> GCC gives warning like:
>> /tmp/t.c:2:1: warning: asm declaration ignored due to conflict with
>> previous rename [-Wpragmas]
>>  extern long double acoshl (long double) __asm__ ("" "__acoshl_finite") ;
>>
>
> That's the same case as in this testcase:
>
>   void foo() __asm__("one");
>   void foo() __asm__("two");
>   void test() { foo(); }
>
> GCC emits a call to 'one' while Clang emits a call to 'two'. This is a
> real bug. Please don't downgrade this to a warning.
>
> As an alternative, I would accept a patch which changes how clang
> generates code so that it also produces a call to 'one', with a warning. It
> looks like what we need to do is drop subsequent asm label declarations on
> functions that already have one.
>
> Nick
>
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


PATCH: error on code that redeclares with an __asm__ label after the first ODR use

2015-12-10 Thread Nick Lewycky via cfe-commits
PR22830 shows a case where some code was adding an __asm__ label after the
first use of a function. GCC and Clang diverged on this code, GCC emitting
the name in the last __asm__ label for all uses while clang would switch in
the middle of the TU as the redeclaration was parsed. The attached patch
detects this case and issues an error on such a redeclaration. If this
breaks real code, we can turn it down to a warning.

Please review!

Nick
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 255303)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -4256,6 +4256,8 @@
 def err_conflicting_types : Error<"conflicting types for %0">;
 def err_different_pass_object_size_params : Error<
   "conflicting pass_object_size attributes on parameters">;
+def err_late_asm_label_name : Error<
+  "cannot apply asm label to %select{variable|function}0 after its first use">;
 def err_nested_redefinition : Error<"nested redefinition of %0">;
 def err_use_with_wrong_tag : Error<
   "use of %0 with tag type that does not match previous declaration">;
Index: lib/Sema/SemaDecl.cpp
===
--- lib/Sema/SemaDecl.cpp	(revision 255303)
+++ lib/Sema/SemaDecl.cpp	(working copy)
@@ -2379,9 +2379,17 @@
   if (!Old->hasAttrs() && !New->hasAttrs())
 return;
 
-  // attributes declared post-definition are currently ignored
+  // Attributes declared post-definition are currently ignored.
   checkNewAttributesAfterDef(*this, New, Old);
 
+  // Check whether this redeclaration adds an __asm__ label name to a
+  // declaration that has already been used.
+  if (Old->isUsed() && !Old->hasAttr() &&
+  New->hasAttr()) {
+Diag(New->getLocation(), diag::err_late_asm_label_name)
+  << isa(Old) << New->getAttr()->getRange();
+  }
+
   if (!Old->hasAttrs())
 return;
 
Index: test/Sema/asm-label.c
===
--- test/Sema/asm-label.c	(revision 0)
+++ test/Sema/asm-label.c	(working copy)
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -verify %s
+
+void f();
+void g();
+void f() __asm__("fish");
+
+void f() {
+  g();
+}
+void g() __asm__("gold");  // expected-error{{cannot apply asm label to function after its first use}}
+
+int x;
+int y;
+int x __asm__("xenon");
+
+int test() { return y; }
+
+int y __asm__("yacht");   // expected-error{{cannot apply asm label to variable after its first use}}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: PATCH: error on code that redeclares with an __asm__ label after the first ODR use

2015-12-11 Thread Nick Lewycky via cfe-commits
On 10 December 2015 at 17:42, Gao, Yunzhong <
yunzhong_...@playstation.sony.com> wrote:

> Out of curiosity, is the following test case possible too?
>
>
>
> void f();
>
> void g() __asm__(“real_g”); // rename g into real_g.
>
>
>
> void f() {
>
>   g(); // this would actually be calling real_g()
>
> }
>
> void real_g() __asm__("gold");  // re-declaring real_g() into gold <--
> should this be an error too?
>

I can't see any reason why not. Both clang and gcc will emit "real_g" here
instead of "gold", but changing the asm label in a program is highly
dubious. I added an error for this too.

Thanks!


> *From:* cfe-commits [mailto:cfe-commits-boun...@lists.llvm.org] *On
> Behalf Of *Nick Lewycky via cfe-commits
> *Sent:* Thursday, December 10, 2015 3:15 PM
> *To:* Clang Commits
> *Subject:* PATCH: error on code that redeclares with an __asm__ label
> after the first ODR use
>
>
>
> PR22830 shows a case where some code was adding an __asm__ label after the
> first use of a function. GCC and Clang diverged on this code, GCC emitting
> the name in the last __asm__ label for all uses while clang would switch in
> the middle of the TU as the redeclaration was parsed. The attached patch
> detects this case and issues an error on such a redeclaration. If this
> breaks real code, we can turn it down to a warning.
>
>
>
> Please review!
>
>
>
> Nick
>
>
>


pr22830-2.patch
Description: Binary data
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: PATCH: error on code that redeclares with an __asm__ label after the first ODR use

2015-12-11 Thread Nick Lewycky via cfe-commits
On 11 December 2015 at 12:57, Richard Smith  wrote:

> On Fri, Dec 11, 2015 at 12:43 PM, Gao, Yunzhong via cfe-commits <
> cfe-commits@lists.llvm.org> wrote:
>
>> gcc 4.8.2 accepts the following case silently without error or warning:
>>
>>   void f();
>>
>>   void g() __asm__(“real_g”);
>>
>>   void f() { g(); }  // gcc emits a call to real_g() here
>>
>>   void real_g() __asm__(“gold”);
>>
>> void real_g() { } // gcc generates a body for gold() here
>>
>>
>>
>> gcc 4.8.2 generates a warning for the following test case:
>>
>> void g() __asm__(“func1”);
>>
>> void g() __asm__(“func2”); // gcc generates a warning and ignores this
>> asm label
>>
>> void g() { }
>>
>>
>>
>> Comparing to gcc behavior, I think it is better to emit error in both
>> cases.
>>
>
> Why? I don't see anything wrong with the first example. We have a function
> whose source-level name is "g()" and whose asm name is "real_g", and we
> have a function whose source-level name is "real_g()" and whose asm name is
> "gold". What's wrong with that?
>

Hah, I completely misread the example and fixed something else. What I
added an error for is:

  void f() __asm__("something");
  void f() __asm__("somethingelse");

With my patch, we don't issue an error on the case Yunzhong actually
supplied. Joerg has pointed out over IRC that this is a really useful
construct and that NetBSD's stack smashing protection uses it. We shouldn't
break that. I've added a testcase to make sure it continues working. Please
review!

Nick

Looks good to me. Thanks!
>>
>> - Gao
>>
>>
>>
>>
>>
>> *From:* Nick Lewycky [mailto:nlewy...@google.com]
>> *Sent:* Friday, December 11, 2015 12:44 AM
>> *To:* Gao, Yunzhong
>> *Cc:* Clang Commits
>> *Subject:* Re: PATCH: error on code that redeclares with an __asm__
>> label after the first ODR use
>>
>>
>>
>> On 10 December 2015 at 17:42, Gao, Yunzhong <
>> yunzhong_...@playstation.sony.com> wrote:
>>
>> Out of curiosity, is the following test case possible too?
>>
>>
>>
>> void f();
>>
>> void g() __asm__(“real_g”); // rename g into real_g.
>>
>>
>>
>> void f() {
>>
>>   g(); // this would actually be calling real_g()
>>
>> }
>>
>> void real_g() __asm__("gold");  // re-declaring real_g() into gold <--
>> should this be an error too?
>>
>>
>>
>> I can't see any reason why not. Both clang and gcc will emit "real_g"
>> here instead of "gold", but changing the asm label in a program is highly
>> dubious. I added an error for this too.
>>
>>
>>
>> Thanks!
>>
>>
>>
>> *From:* cfe-commits [mailto:cfe-commits-boun...@lists.llvm.org] *On
>> Behalf Of *Nick Lewycky via cfe-commits
>> *Sent:* Thursday, December 10, 2015 3:15 PM
>> *To:* Clang Commits
>> *Subject:* PATCH: error on code that redeclares with an __asm__ label
>> after the first ODR use
>>
>>
>>
>> PR22830 shows a case where some code was adding an __asm__ label after
>> the first use of a function. GCC and Clang diverged on this code, GCC
>> emitting the name in the last __asm__ label for all uses while clang would
>> switch in the middle of the TU as the redeclaration was parsed. The
>> attached patch detects this case and issues an error on such a
>> redeclaration. If this breaks real code, we can turn it down to a warning.
>>
>>
>>
>> Please review!
>>
>>
>>
>> Nick
>>
>>
>>
>>
>>
>> ___
>> cfe-commits mailing list
>> cfe-commits@lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>
>>
>
Index: include/clang/Basic/DiagnosticSemaKinds.td
===
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 255303)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -4256,6 +4256,9 @@
 def err_conflicting_types : Error<"conflicting types for %0">;
 def err_different_pass_object_size_params : Error<
   "conflicting pass_object_size attributes on parameters">;
+def err_late_asm_label_name : Error<
+  "cannot apply asm label to %select{variable|function}0 after its first use">;
+def err_different_asm_label : Error<"conflicting asm label">;
 def err_ne

r255371 - Error on redeclaring with a conflicting asm label and on redeclaring with an asm label after the first ODR-use. Detects problems like the one in PR22830 where gcc and clang both compiled the

2015-12-11 Thread Nick Lewycky via cfe-commits
Author: nicholas
Date: Fri Dec 11 15:28:55 2015
New Revision: 255371

URL: http://llvm.org/viewvc/llvm-project?rev=255371&view=rev
Log:
Error on redeclaring with a conflicting asm label and on redeclaring with an 
asm label after the first ODR-use. Detects problems like the one in PR22830 
where gcc and clang both compiled the file but with different behaviour.

Added:
cfe/trunk/test/Sema/asm-label.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaDecl.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=255371&r1=255370&r2=255371&view=diff
==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Dec 11 15:28:55 
2015
@@ -4259,6 +4259,9 @@ def err_tag_definition_of_typedef : Erro
 def err_conflicting_types : Error<"conflicting types for %0">;
 def err_different_pass_object_size_params : Error<
   "conflicting pass_object_size attributes on parameters">;
+def err_late_asm_label_name : Error<
+  "cannot apply asm label to %select{variable|function}0 after its first use">;
+def err_different_asm_label : Error<"conflicting asm label">;
 def err_nested_redefinition : Error<"nested redefinition of %0">;
 def err_use_with_wrong_tag : Error<
   "use of %0 with tag type that does not match previous declaration">;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=255371&r1=255370&r2=255371&view=diff
==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Dec 11 15:28:55 2015
@@ -2379,9 +2379,24 @@ void Sema::mergeDeclAttributes(NamedDecl
   if (!Old->hasAttrs() && !New->hasAttrs())
 return;
 
-  // attributes declared post-definition are currently ignored
+  // Attributes declared post-definition are currently ignored.
   checkNewAttributesAfterDef(*this, New, Old);
 
+  if (AsmLabelAttr *NewA = New->getAttr()) {
+if (AsmLabelAttr *OldA = Old->getAttr()) {
+  if (OldA->getLabel() != NewA->getLabel()) {
+// This redeclaration changes __asm__ label.
+Diag(New->getLocation(), diag::err_different_asm_label);
+Diag(OldA->getLocation(), diag::note_previous_declaration);
+  }
+} else if (Old->isUsed()) {
+  // This redeclaration adds an __asm__ label to a declaration that has
+  // already been ODR-used.
+  Diag(New->getLocation(), diag::err_late_asm_label_name)
+<< isa(Old) << New->getAttr()->getRange();
+}
+  }
+
   if (!Old->hasAttrs())
 return;
 

Added: cfe/trunk/test/Sema/asm-label.c
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/asm-label.c?rev=255371&view=auto
==
--- cfe/trunk/test/Sema/asm-label.c (added)
+++ cfe/trunk/test/Sema/asm-label.c Fri Dec 11 15:28:55 2015
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -verify %s
+
+void f();
+void f() __asm__("fish");
+void g();
+
+void f() {
+  g();
+}
+void g() __asm__("gold");  // expected-error{{cannot apply asm label to 
function after its first use}}
+
+void h() __asm__("hose");  // expected-note{{previous declaration is here}}
+void h() __asm__("hair");  // expected-error{{conflicting asm label}}
+
+int x;
+int x __asm__("xenon");
+int y;
+
+int test() { return y; }
+
+int y __asm__("yacht");  // expected-error{{cannot apply asm label to variable 
after its first use}}
+
+int z __asm__("zebra");  // expected-note{{previous declaration is here}}
+int z __asm__("zooms");  // expected-error{{conflicting asm label}}
+
+
+// No diagnostics on the following.
+void __real_readlink() __asm("readlink");
+void readlink() __asm("__protected_readlink");
+void readlink() { __real_readlink(); }


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


Re: r255371 - Error on redeclaring with a conflicting asm label and on redeclaring with an asm label after the first ODR-use. Detects problems like the one in PR22830 where gcc and clang both compiled

2015-12-17 Thread Nick Lewycky via cfe-commits

On 12/17/2015 10:47 AM, Kostya Serebryany wrote:

I am now observing this error message when building glibc with clang
(from trunk):
../include/string.h:101:28: error: cannot apply asm label to function
after its first use
libc_hidden_builtin_proto (memcpy)
(many more instances)


Do you think this is a bug in glibc code, or the error message could be
more relaxed?


Could you email me a .i copy of a failing build? That will help me 
decide whether it's a bug in the error or in glibc.








On Fri, Dec 11, 2015 at 1:28 PM, Nick Lewycky via cfe-commits
mailto:cfe-commits@lists.llvm.org>> wrote:

Author: nicholas
Date: Fri Dec 11 15:28:55 2015
New Revision: 255371

URL: http://llvm.org/viewvc/llvm-project?rev=255371&view=rev
Log:
Error on redeclaring with a conflicting asm label and on redeclaring
with an asm label after the first ODR-use. Detects problems like the
one in PR22830 where gcc and clang both compiled the file but with
different behaviour.

Added:
 cfe/trunk/test/Sema/asm-label.c
Modified:
 cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
 cfe/trunk/lib/Sema/SemaDecl.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL:

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

==
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Dec 11
15:28:55 2015
@@ -4259,6 +4259,9 @@ def err_tag_definition_of_typedef : Erro
  def err_conflicting_types : Error<"conflicting types for %0">;
  def err_different_pass_object_size_params : Error<
"conflicting pass_object_size attributes on parameters">;
+def err_late_asm_label_name : Error<
+  "cannot apply asm label to %select{variable|function}0 after its
first use">;
+def err_different_asm_label : Error<"conflicting asm label">;
  def err_nested_redefinition : Error<"nested redefinition of %0">;
  def err_use_with_wrong_tag : Error<
"use of %0 with tag type that does not match previous declaration">;

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL:

http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=255371&r1=255370&r2=255371&view=diff

==
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Dec 11 15:28:55 2015
@@ -2379,9 +2379,24 @@ void Sema::mergeDeclAttributes(NamedDecl
if (!Old->hasAttrs() && !New->hasAttrs())
  return;

-  // attributes declared post-definition are currently ignored
+  // Attributes declared post-definition are currently ignored.
checkNewAttributesAfterDef(*this, New, Old);

+  if (AsmLabelAttr *NewA = New->getAttr()) {
+if (AsmLabelAttr *OldA = Old->getAttr()) {
+  if (OldA->getLabel() != NewA->getLabel()) {
+// This redeclaration changes __asm__ label.
+Diag(New->getLocation(), diag::err_different_asm_label);
+Diag(OldA->getLocation(), diag::note_previous_declaration);
+  }
+} else if (Old->isUsed()) {
+  // This redeclaration adds an __asm__ label to a declaration
that has
+  // already been ODR-used.
+  Diag(New->getLocation(), diag::err_late_asm_label_name)
+<< isa(Old) <<
New->getAttr()->getRange();
+}
+  }
+
if (!Old->hasAttrs())
  return;


Added: cfe/trunk/test/Sema/asm-label.c
URL:

http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/asm-label.c?rev=255371&view=auto

==
--- cfe/trunk/test/Sema/asm-label.c (added)
+++ cfe/trunk/test/Sema/asm-label.c Fri Dec 11 15:28:55 2015
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -verify %s
+
+void f();
+void f() __asm__("fish");
+void g();
+
+void f() {
+  g();
+}
+void g() __asm__("gold");  // expected-error{{cannot apply asm
label to function after its first use}}
+
+void h() __asm__("hose");  // expected-note{{previous declaration
is here}}
+void h() __asm__("hair");  // expected-error{{conflicting asm label}}
+
+int x;
+int x __asm__("xenon");
+int y;
+
+int test() { return y; }
+
+int y __asm__("yacht");  // expected-error{{cannot apply asm label
to variable after its first use}}
+
+int z __asm__("