[PATCH] D33305: [ubsan] Add a check for pointer overflow UB

2017-06-07 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

Just a heads up that I ran into an arguably somewhat unexpected instance of 
this with (a copy of the Graphite project included in) LibreOffice, see the 
commit message of 
https://cgit.freedesktop.org/libreoffice/core/commit/?id=681b4a49d797996229513d3e842d2a431030730a
 "external/graphite: Avoid -fsanitize=pointer-overflow" for details.  (In 
short,  "ptrdiff_t d = ...; T * p += d / sizeof(T);" can trigger an overflow 
warning when d is negative.)


Repository:
  rL LLVM

https://reviews.llvm.org/D33305



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


[PATCH] D33030: [libcxxabi] Align unwindHeader on a double-word boundary

2017-06-20 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

In LibreOffice we unfortunately have some dirty code that synthesizes exception 
throwing, calling `__cxa_allocate_exception`, `__cxa_throw` (passing in our own 
exception destructor function), and then, when the exception destructor 
function gets called, assumes we can map from the passed pointer to the 
`__cxa_exception` header preceding it (to get at its `exceptionType` member).  
That code was thus broken by this change.  I have a dirty hack around that 
(checking whether the `__cxa_exception` `exceptionDestructor` member has the 
expected value; if not, adjust: Hack to dynamically adapt to __cxa_exceptiom in 
LLVM 5.0 libcxxabi 
)
 and two questions:

- Is there any estimation when this change will show up in macOS's libcxxabi?  
That would give me an idea which LibreOffice versions I would need to backport 
my fix to.

- Does anybody happen to have a good idea how to do my hacky fix in a cleaner 
way?


Repository:
  rL LLVM

https://reviews.llvm.org/D33030



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


[PATCH] D34417: Switch TestVisitor to Lang_C via -x c

2017-06-20 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.

...instead of -std=c99, as the latter lead to

  error: invalid argument '-std=c99' not allowed with 'C++'

complaints in test logs


https://reviews.llvm.org/D34417

Files:
  unittests/Tooling/TestVisitor.h


Index: unittests/Tooling/TestVisitor.h
===
--- unittests/Tooling/TestVisitor.h
+++ unittests/Tooling/TestVisitor.h
@@ -53,7 +53,10 @@
   bool runOver(StringRef Code, Language L = Lang_CXX) {
 std::vector Args;
 switch (L) {
-  case Lang_C: Args.push_back("-std=c99"); break;
+  case Lang_C:
+Args.push_back("-x");
+Args.push_back("c");
+break;
   case Lang_CXX98: Args.push_back("-std=c++98"); break;
   case Lang_CXX11: Args.push_back("-std=c++11"); break;
   case Lang_CXX14: Args.push_back("-std=c++14"); break;


Index: unittests/Tooling/TestVisitor.h
===
--- unittests/Tooling/TestVisitor.h
+++ unittests/Tooling/TestVisitor.h
@@ -53,7 +53,10 @@
   bool runOver(StringRef Code, Language L = Lang_CXX) {
 std::vector Args;
 switch (L) {
-  case Lang_C: Args.push_back("-std=c99"); break;
+  case Lang_C:
+Args.push_back("-x");
+Args.push_back("c");
+break;
   case Lang_CXX98: Args.push_back("-std=c++98"); break;
   case Lang_CXX11: Args.push_back("-std=c++11"); break;
   case Lang_CXX14: Args.push_back("-std=c++14"); break;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D34419: Make sure TraverseInitListExpr visits InitListExpr exactly twice

2017-06-20 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.

... once each for the syntactic and semantic form. Without this fix, behavior 
of the newly added tests would have been

InitListExprIsPreOrderVisitedTwice:
 syntactic: 1
 semantic:  2

InitListExprIsPostOrderVisitedTwice:
 syntactic: 0
 semantic:  1

InitListExprIsPreOrderNoQueueVisitedTwice:
 syntactic: 1
 semantic:  2

InitListExprIsPostOrderNoQueueVisitedTwice:
 syntactic: 0
 semantic:  2


https://reviews.llvm.org/D34419

Files:
  include/clang/AST/RecursiveASTVisitor.h
  unittests/Tooling/RecursiveASTVisitorTest.cpp

Index: unittests/Tooling/RecursiveASTVisitorTest.cpp
===
--- unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -158,4 +158,90 @@
   "static int k = f();\n"));
 }
 
+// Check to ensure that InitListExpr is visited twice, once each for the
+// syntactic and semantic form.
+class InitListExprPreOrderVisitor
+: public ExpectedLocationVisitor {
+public:
+  bool VisitInitListExpr(InitListExpr *ILE) {
+Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart());
+return true;
+  }
+};
+
+class InitListExprPostOrderVisitor
+: public ExpectedLocationVisitor {
+public:
+  bool shouldTraversePostOrder() const { return true; }
+
+  bool VisitInitListExpr(InitListExpr *ILE) {
+Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart());
+return true;
+  }
+};
+
+class InitListExprPreOrderNoQueueVisitor
+: public ExpectedLocationVisitor {
+public:
+  bool TraverseInitListExpr(InitListExpr *ILE) {
+return ExpectedLocationVisitor::TraverseInitListExpr(ILE);
+  }
+
+  bool VisitInitListExpr(InitListExpr *ILE) {
+Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart());
+return true;
+  }
+};
+
+class InitListExprPostOrderNoQueueVisitor
+: public ExpectedLocationVisitor {
+public:
+  bool shouldTraversePostOrder() const { return true; }
+
+  bool TraverseInitListExpr(InitListExpr *ILE) {
+return ExpectedLocationVisitor::TraverseInitListExpr(ILE);
+  }
+
+  bool VisitInitListExpr(InitListExpr *ILE) {
+Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart());
+return true;
+  }
+};
+
+TEST(RecursiveASTVisitor, InitListExprIsPreOrderVisitedTwice) {
+  InitListExprPreOrderVisitor Visitor;
+  Visitor.ExpectMatch("syntactic", 2, 21);
+  Visitor.ExpectMatch("semantic", 2, 21);
+  EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n"
+  "static struct S s = {.x = 0};\n",
+  InitListExprPreOrderVisitor::Lang_C));
+}
+
+TEST(RecursiveASTVisitor, InitListExprIsPostOrderVisitedTwice) {
+  InitListExprPostOrderVisitor Visitor;
+  Visitor.ExpectMatch("syntactic", 2, 21);
+  Visitor.ExpectMatch("semantic", 2, 21);
+  EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n"
+  "static struct S s = {.x = 0};\n",
+  InitListExprPostOrderVisitor::Lang_C));
+}
+
+TEST(RecursiveASTVisitor, InitListExprIsPreOrderNoQueueVisitedTwice) {
+  InitListExprPreOrderNoQueueVisitor Visitor;
+  Visitor.ExpectMatch("syntactic", 2, 21);
+  Visitor.ExpectMatch("semantic", 2, 21);
+  EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n"
+  "static struct S s = {.x = 0};\n",
+  InitListExprPreOrderNoQueueVisitor::Lang_C));
+}
+
+TEST(RecursiveASTVisitor, InitListExprIsPostOrderNoQueueVisitedTwice) {
+  InitListExprPostOrderNoQueueVisitor Visitor;
+  Visitor.ExpectMatch("syntactic", 2, 21);
+  Visitor.ExpectMatch("semantic", 2, 21);
+  EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n"
+  "static struct S s = {.x = 0};\n",
+  InitListExprPostOrderNoQueueVisitor::Lang_C));
+}
+
 } // end anonymous namespace
Index: include/clang/AST/RecursiveASTVisitor.h
===
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -593,6 +593,16 @@
 #define STMT(CLASS, PARENT)\
   case Stmt::CLASS##Class: \
 TRY_TO(WalkUpFrom##CLASS(static_cast(S))); break;
+#define INITLISTEXPR(CLASS, PARENT)\
+  case Stmt::CLASS##Class: \
+{  \
+  auto ILE = static_cast(S);  \
+  if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE)\
+TRY_TO(WalkUpFrom##CLASS(Syn));\
+  if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \
+TRY_TO(WalkUpFrom##CLASS(Sem));  

[PATCH] D22128: Make CastExpr::getSubExprAsWritten look through implicit temporary under CK_ConstructorConversion

2017-06-21 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 103449.
sberg added a comment.
Herald added subscribers: kristof.beyls, mgorny, klimek.

added test


https://reviews.llvm.org/D22128

Files:
  lib/AST/Expr.cpp
  unittests/Tooling/CMakeLists.txt
  unittests/Tooling/CastExprTest.cpp

Index: unittests/Tooling/CastExprTest.cpp
===
--- /dev/null
+++ unittests/Tooling/CastExprTest.cpp
@@ -0,0 +1,38 @@
+//===- unittest/Tooling/CastExprTest.cpp --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#include "TestVisitor.h"
+
+using namespace clang;
+
+namespace {
+
+struct CastExprVisitor : TestVisitor {
+  std::function OnExplicitCast;
+
+  bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) {
+if (OnExplicitCast)
+  OnExplicitCast(Expr);
+return true;
+  }
+};
+
+TEST(CastExprTest, GetSubExprAsWrittenThroughMaterializedTemporary) {
+CastExprVisitor Visitor;
+Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) {
+  auto Sub = Expr->getSubExprAsWritten();
+  EXPECT_TRUE(isa(Sub))
+<< "Expected DeclRefExpr, but saw " << Sub->getStmtClassName();
+};
+Visitor.runOver("struct S1 {};\n"
+"struct S2 { operator S1(); };\n"
+"S1 f(S2 s) { return static_cast(s); }\n");
+}
+
+}
Index: unittests/Tooling/CMakeLists.txt
===
--- unittests/Tooling/CMakeLists.txt
+++ unittests/Tooling/CMakeLists.txt
@@ -11,6 +11,7 @@
 endif()
 
 add_clang_unittest(ToolingTests
+  CastExprTest.cpp
   CommentHandlerTest.cpp
   CompilationDatabaseTest.cpp
   FixItTest.cpp
Index: lib/AST/Expr.cpp
===
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -1641,25 +1641,32 @@
   llvm_unreachable("Unhandled cast kind!");
 }
 
+namespace {
+  Expr *skipImplicitTemporary(Expr *expr) {
+// Skip through reference binding to temporary.
+if (MaterializeTemporaryExpr *Materialize
+  = dyn_cast(expr))
+  expr = Materialize->GetTemporaryExpr();
+
+// Skip any temporary bindings; they're implicit.
+if (CXXBindTemporaryExpr *Binder = dyn_cast(expr))
+  expr = Binder->getSubExpr();
+
+return expr;
+  }
+}
+
 Expr *CastExpr::getSubExprAsWritten() {
   Expr *SubExpr = nullptr;
   CastExpr *E = this;
   do {
-SubExpr = E->getSubExpr();
+SubExpr = skipImplicitTemporary(E->getSubExpr());
 
-// Skip through reference binding to temporary.
-if (MaterializeTemporaryExpr *Materialize 
-  = dyn_cast(SubExpr))
-  SubExpr = Materialize->GetTemporaryExpr();
-
-// Skip any temporary bindings; they're implicit.
-if (CXXBindTemporaryExpr *Binder = dyn_cast(SubExpr))
-  SubExpr = Binder->getSubExpr();
-
 // Conversions by constructor and conversion functions have a
 // subexpression describing the call; strip it off.
 if (E->getCastKind() == CK_ConstructorConversion)
-  SubExpr = cast(SubExpr)->getArg(0);
+  SubExpr =
+skipImplicitTemporary(cast(SubExpr)->getArg(0));
 else if (E->getCastKind() == CK_UserDefinedConversion) {
   assert((isa(SubExpr) ||
   isa(SubExpr)) &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2017-12-18 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rC320978: No -fsanitize=function warning when calling noexcept 
function through non… (authored by sberg, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D40720?vs=125152&id=127340#toc

Repository:
  rC Clang

https://reviews.llvm.org/D40720

Files:
  lib/CodeGen/CGExpr.cpp


Index: lib/CodeGen/CGExpr.cpp
===
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -4504,10 +4504,14 @@
   Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst);
   llvm::Constant *StaticData[] = {
 EmitCheckSourceLocation(E->getLocStart()),
-EmitCheckTypeDescriptor(CalleeType)
+EmitCheckTypeDescriptor(CalleeType),
+cast(FnType)->isNothrow(getContext())
+  ? llvm::Constant::getNullValue(FTRTTIConst->getType())
+  : FTRTTIConst
   };
   EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
-SanitizerHandler::FunctionTypeMismatch, StaticData, CalleePtr);
+SanitizerHandler::FunctionTypeMismatch, StaticData,
+{CalleePtr, CalleeRTTI});
 
   Builder.CreateBr(Cont);
   EmitBlock(Cont);


Index: lib/CodeGen/CGExpr.cpp
===
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -4504,10 +4504,14 @@
   Builder.CreateICmpEQ(CalleeRTTI, FTRTTIConst);
   llvm::Constant *StaticData[] = {
 EmitCheckSourceLocation(E->getLocStart()),
-EmitCheckTypeDescriptor(CalleeType)
+EmitCheckTypeDescriptor(CalleeType),
+cast(FnType)->isNothrow(getContext())
+  ? llvm::Constant::getNullValue(FTRTTIConst->getType())
+  : FTRTTIConst
   };
   EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
-SanitizerHandler::FunctionTypeMismatch, StaticData, CalleePtr);
+SanitizerHandler::FunctionTypeMismatch, StaticData,
+{CalleePtr, CalleeRTTI});
 
   Builder.CreateBr(Cont);
   EmitBlock(Cont);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2017-12-18 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg reopened this revision.
sberg added a comment.

Had to revert r320977/r320978 again with r320981/r320982:  "At least 
http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-android/builds/6013/steps/annotate/logs/stdio
 complains about
ubsan::ubsan_handle_function_type_mismatch_abort (compiler-rt 
lib/ubsan/ubsan_handlers.cc) returning now despite being declared 'noreturn', 
so looks like a different approach is needed for the function_type_mismatch 
check
to be called also in cases that may ultimately succeed."

Any hint how to achieve that properly?


Repository:
  rC Clang

https://reviews.llvm.org/D40720



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


[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2017-12-18 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

In https://reviews.llvm.org/D40720#958677, @vsk wrote:

> Please add a test.


Note that the bot upon the first closing of this review changed the shown diff 
from the combined cfe+compiler-rt diff to just the cfe part.  See 
https://reviews.llvm.org/rL320977 for the compiler-rt part, including tests in 
compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/Function/function.cpp.


Repository:
  rC Clang

https://reviews.llvm.org/D40720



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


[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2017-12-19 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

In https://reviews.llvm.org/D40720#958743, @vsk wrote:

> > Would it be possible to fix this by stripping the noexcept specifiers from 
> > both the function type used in the check and the one that is embedded in 
> > the prefix data? The downside is that we won't catch the case where the 
> > caller has a noexcept specifier and the callee doesn't, but that seems like 
> > an edge case to me, and we can think about fixing it in other ways later.
>
> This sounds fine to me, and it avoids breaking the trapping mode.


...and would be in line with what has been discussed in the mail sub-thread 
starting at 
http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20171218/213093.html 
"Re: r320982 - Revert r320978 'No -fsanitize=function warning when calling 
noexcept function through non-noexcept pointer in C++17'"


Repository:
  rC Clang

https://reviews.llvm.org/D40720



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


[PATCH] D40295: -fsanitize=vptr warnings on bad static types in dynamic_cast and typeid

2017-12-20 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 127676.
sberg added a comment.

added a small IR test


https://reviews.llvm.org/D40295

Files:
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/test/CodeGenCXX/ubsan-vtable-checks.cpp
  compiler-rt/lib/ubsan/ubsan_handlers.cc
  compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp

Index: compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp
===
--- compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp
+++ compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp
@@ -1,41 +1,53 @@
-// RUN: %clangxx -frtti -fsanitize=null,vptr -fno-sanitize-recover=null,vptr -g %s -O3 -o %t -mllvm -enable-tail-merge=false
-// RUN: %run %t rT && %run %t mT && %run %t fT && %run %t cT
-// RUN: %run %t rU && %run %t mU && %run %t fU && %run %t cU
-// RUN: %run %t rS && %run %t rV && %run %t oV
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --check-prefix=CHECK-%os-OFFSET --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
-// RUN: not %run %t nN 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMFUN --strict-whitespace
+// RUN: %clangxx -frtti -fsanitize=null,vptr -g %s -O3 -o %t -mllvm -enable-tail-merge=false
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t mT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t fT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t cT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t mU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t fU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t cU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rS
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rV
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t oV
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t zN
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --check-prefix=CHECK-%os-OFFSET --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1 not %run %t nN 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMFUN --strict-whitespace
+// RUN: %env_ubsan_opts=print_stacktrace=1 %run %t dT 2>&1 | FileCheck %s --check-prefix=CHECK-DYNAMIC --check-prefix=CHECK-%os-DYNAMIC --strict-whitespace
 
 // RUN: (echo 

[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2017-12-21 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 127863.
sberg added a comment.

As suggested, solve the issue instead by removing any "noexcept" from the 
typeinfo emitted for the -fsanitize=function checks.


https://reviews.llvm.org/D40720

Files:
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenTypes.cpp
  clang/lib/CodeGen/CodeGenTypes.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
  compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp

Index: compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
===
--- compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
+++ compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -fsanitize=function %s -O3 -g -o %t
+// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t
 // RUN: %run %t 2>&1 | FileCheck %s
 // Verify that we can disable symbolization if needed:
 // RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
@@ -23,9 +23,49 @@
   reinterpret_cast(reinterpret_cast(f))(42);
 }
 
+void f1(int) {}
+void f2(unsigned int) {}
+void f3(int) noexcept {}
+void f4(unsigned int) noexcept {}
+
+void check_noexcept_calls() {
+  void (*p1)(int);
+  p1 = &f1;
+  p1(0);
+  p1 = reinterpret_cast(&f2);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+  p1(0);
+  p1 = &f3;
+  p1(0);
+  p1 = reinterpret_cast(&f4);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+  p1(0);
+
+  void (*p2)(int) noexcept;
+  p2 = reinterpret_cast(&f1);
+  // TODO: Unclear whether calling a non-noexcept function through a pointer to
+  // nexcept function should cause an error.
+  // CHECK-NOT: function.cpp:[[@LINE+2]]:3: runtime error: call to function f1(int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM-NOT: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+  p2 = reinterpret_cast(&f2);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+  p2 = &f3;
+  p2(0);
+  p2 = reinterpret_cast(&f4);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+}
+
 int main(void) {
   make_valid_call();
   make_invalid_call();
+  check_noexcept_calls();
   // Check that no more errors will be printed.
   // CHECK-NOT: runtime error: call to function
   // NOSYM-NOT: runtime error: call to function
Index: clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++17 -fsanitize=function -emit-llvm -triple x86_64-linux-gnu %s -o - | FileCheck %s
+
+// Check that typeinfo recorded in function prolog doesn't have "Do" noexcept
+// qualifier in its mangled name.
+// CHECK: @[[LABEL:[0-9]+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*)
+// CHECK: define void @_Z1fv() #{{.*}} prologue <{ i32, i32 }> <{ i32 {{.*}}, i32 trunc (i64 sub (i64 ptrtoint (i8** @[[LABEL]] to i64), i64 ptrtoint (void ()* @_Z1fv to i64)) to i32) }>
+void f() noexcept {}
+
+// CHECK: define void @_Z1gPDoFvvE
+void g(void (*p)() noexcept) {
+  // Check that reference typeinfo at call site doesn't have "Do" noexcept
+  // qualifier in its mangled name, either.
+  // CHECK: icmp eq i8* %{{.*}}, bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*), !nosanitize
+  p();
+}
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3415,7 +3415,7 @@
 
 /// Compute the flags for a __pbase_type_info, and remove the corresponding
 /// pieces from \p Type.
-static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type) {
+static unsigned extractPBaseFlags(CodeGe

[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2017-12-21 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 127899.
sberg added a comment.

(need to call getAs instead of cast in 
one place, in case the name in the function decl is wrapped in parens, as 
happens in HarfBuzz's hb-buffer.cc)


https://reviews.llvm.org/D40720

Files:
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/CodeGenTypes.cpp
  clang/lib/CodeGen/CodeGenTypes.h
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
  compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp

Index: compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
===
--- compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
+++ compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -fsanitize=function %s -O3 -g -o %t
+// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t
 // RUN: %run %t 2>&1 | FileCheck %s
 // Verify that we can disable symbolization if needed:
 // RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
@@ -23,9 +23,49 @@
   reinterpret_cast(reinterpret_cast(f))(42);
 }
 
+void f1(int) {}
+void f2(unsigned int) {}
+void f3(int) noexcept {}
+void f4(unsigned int) noexcept {}
+
+void check_noexcept_calls() {
+  void (*p1)(int);
+  p1 = &f1;
+  p1(0);
+  p1 = reinterpret_cast(&f2);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+  p1(0);
+  p1 = &f3;
+  p1(0);
+  p1 = reinterpret_cast(&f4);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+  p1(0);
+
+  void (*p2)(int) noexcept;
+  p2 = reinterpret_cast(&f1);
+  // TODO: Unclear whether calling a non-noexcept function through a pointer to
+  // nexcept function should cause an error.
+  // CHECK-NOT: function.cpp:[[@LINE+2]]:3: runtime error: call to function f1(int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM-NOT: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+  p2 = reinterpret_cast(&f2);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+  p2 = &f3;
+  p2(0);
+  p2 = reinterpret_cast(&f4);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+}
+
 int main(void) {
   make_valid_call();
   make_invalid_call();
+  check_noexcept_calls();
   // Check that no more errors will be printed.
   // CHECK-NOT: runtime error: call to function
   // NOSYM-NOT: runtime error: call to function
Index: clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++17 -fsanitize=function -emit-llvm -triple x86_64-linux-gnu %s -o - | FileCheck %s
+
+// Check that typeinfo recorded in function prolog doesn't have "Do" noexcept
+// qualifier in its mangled name.
+// CHECK: @[[LABEL:[0-9]+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*)
+// CHECK: define void @_Z1fv() #{{.*}} prologue <{ i32, i32 }> <{ i32 {{.*}}, i32 trunc (i64 sub (i64 ptrtoint (i8** @[[LABEL]] to i64), i64 ptrtoint (void ()* @_Z1fv to i64)) to i32) }>
+void f() noexcept {}
+
+// CHECK: define void @_Z1gPDoFvvE
+void g(void (*p)() noexcept) {
+  // Check that reference typeinfo at call site doesn't have "Do" noexcept
+  // qualifier in its mangled name, either.
+  // CHECK: icmp eq i8* %{{.*}}, bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*), !nosanitize
+  p();
+}
Index: clang/lib/CodeGen/ItaniumCXXABI.cpp
===
--- clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -3415,7 +3415,7 @@
 
 /// Compute the flags for a __pbase_type_info, and remove the corresponding
 /// pieces from \p Type.
-static unsigned extractPBaseFlags(ASTContext &Ctx, QualType &Type) {
+static unsigned e

[PATCH] D40295: -fsanitize=vptr warnings on bad static types in dynamic_cast and typeid

2017-12-28 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL321518: -fsanitize=vptr warnings on bad static types in 
dynamic_cast and typeid (authored by sberg, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D40295?vs=127676&id=128288#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D40295

Files:
  compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
  compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp

Index: compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
===
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
@@ -38,7 +38,8 @@
 const char *TypeCheckKinds[] = {
 "load of", "store to", "reference binding to", "member access within",
 "member call on", "constructor call on", "downcast of", "downcast of",
-"upcast of", "cast to virtual base of", "_Nonnull binding to"};
+"upcast of", "cast to virtual base of", "_Nonnull binding to",
+"dynamic operation on"};
 }
 
 static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
Index: compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp
===
--- compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp
+++ compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/vptr.cpp
@@ -1,41 +1,53 @@
-// RUN: %clangxx -frtti -fsanitize=null,vptr -fno-sanitize-recover=null,vptr -g %s -O3 -o %t -mllvm -enable-tail-merge=false
-// RUN: %run %t rT && %run %t mT && %run %t fT && %run %t cT
-// RUN: %run %t rU && %run %t mU && %run %t fU && %run %t cU
-// RUN: %run %t rS && %run %t rV && %run %t oV
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --check-prefix=CHECK-%os-OFFSET --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
-// RUN: not %run %t nN 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMFUN --strict-whitespace
+// RUN: %clangxx -frtti -fsanitize=null,vptr -g %s -O3 -o %t -mllvm -enable-tail-merge=false
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t mT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t fT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t cT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t mU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t fU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t cU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rS
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rV
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t oV
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t zN
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t

[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2017-12-28 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 128289.
sberg added a comment.

made the recommended changes


https://reviews.llvm.org/D40720

Files:
  clang/include/clang/AST/ASTContext.h
  clang/lib/AST/ASTContext.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CodeGenFunction.cpp
  clang/lib/CodeGen/ItaniumCXXABI.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
  compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp

Index: compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
===
--- compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
+++ compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -fsanitize=function %s -O3 -g -o %t
+// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t
 // RUN: %run %t 2>&1 | FileCheck %s
 // Verify that we can disable symbolization if needed:
 // RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
@@ -23,9 +23,49 @@
   reinterpret_cast(reinterpret_cast(f))(42);
 }
 
+void f1(int) {}
+void f2(unsigned int) {}
+void f3(int) noexcept {}
+void f4(unsigned int) noexcept {}
+
+void check_noexcept_calls() {
+  void (*p1)(int);
+  p1 = &f1;
+  p1(0);
+  p1 = reinterpret_cast(&f2);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+  p1(0);
+  p1 = &f3;
+  p1(0);
+  p1 = reinterpret_cast(&f4);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+  p1(0);
+
+  void (*p2)(int) noexcept;
+  p2 = reinterpret_cast(&f1);
+  // TODO: Unclear whether calling a non-noexcept function through a pointer to
+  // nexcept function should cause an error.
+  // CHECK-NOT: function.cpp:[[@LINE+2]]:3: runtime error: call to function f1(int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM-NOT: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+  p2 = reinterpret_cast(&f2);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+  p2 = &f3;
+  p2(0);
+  p2 = reinterpret_cast(&f4);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+}
+
 int main(void) {
   make_valid_call();
   make_invalid_call();
+  check_noexcept_calls();
   // Check that no more errors will be printed.
   // CHECK-NOT: runtime error: call to function
   // NOSYM-NOT: runtime error: call to function
Index: clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
===
--- /dev/null
+++ clang/test/CodeGenCXX/ubsan-function-noexcept.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++17 -fsanitize=function -emit-llvm -triple x86_64-linux-gnu %s -o - | FileCheck %s
+
+// Check that typeinfo recorded in function prolog doesn't have "Do" noexcept
+// qualifier in its mangled name.
+// CHECK: @[[RTTI:[0-9]+]] = private constant i8* bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*)
+// CHECK: define void @_Z1fv() #{{.*}} prologue <{ i32, i32 }> <{ i32 {{.*}}, i32 trunc (i64 sub (i64 ptrtoint (i8** @[[RTTI]] to i64), i64 ptrtoint (void ()* @_Z1fv to i64)) to i32) }>
+void f() noexcept {}
+
+// CHECK: define void @_Z1gPDoFvvE
+void g(void (*p)() noexcept) {
+  // Check that reference typeinfo at call site doesn't have "Do" noexcept
+  // qualifier in its mangled name, either.
+  // CHECK: icmp eq i8* %{{.*}}, bitcast ({ i8*, i8* }* @_ZTIFvvE to i8*), !nosanitize
+  p();
+}
Index: clang/lib/Sema/SemaOverload.cpp
===
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -1475,10 +1475,8 @@
 const auto *ToFPT = cast(ToFn);
 if (FromFPT->isNothrow(Context) && !ToFPT->isNothrow(Context)) {
   FromFn = cast(
-  Context.getFunctionType(FromFPT->getReturnType(),
-  FromFPT->getParamTypes(),
-  FromFPT->g

[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2018-01-04 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

friendly ping

any further input, or should I consider this good enough to go in now?


https://reviews.llvm.org/D40720



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


[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2018-01-04 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC321859: No -fsanitize=function warning when calling noexcept 
function through non… (authored by sberg, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D40720?vs=128289&id=128710#toc

Repository:
  rC Clang

https://reviews.llvm.org/D40720

Files:
  include/clang/AST/ASTContext.h
  lib/AST/ASTContext.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CodeGenFunction.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Sema/SemaOverload.cpp

Index: include/clang/AST/ASTContext.h
===
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1162,6 +1162,13 @@
   /// \brief Change the result type of a function type once it is deduced.
   void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType);
 
+  /// Get a function type and produce the equivalent function type with the
+  /// specified exception specification. Type sugar that can be present on a
+  /// declaration of a function with an exception specification is permitted
+  /// and preserved. Other type sugar (for instance, typedefs) is not.
+  QualType getFunctionTypeWithExceptionSpec(
+  QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI);
+
   /// \brief Determine whether two function types are the same, ignoring
   /// exception specifications in cases where they're part of the type.
   bool hasSameFunctionTypeIgnoringExceptionSpec(QualType T, QualType U);
Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -2582,44 +2582,42 @@
 /// specified exception specification. Type sugar that can be present on a
 /// declaration of a function with an exception specification is permitted
 /// and preserved. Other type sugar (for instance, typedefs) is not.
-static QualType getFunctionTypeWithExceptionSpec(
-ASTContext &Context, QualType Orig,
-const FunctionProtoType::ExceptionSpecInfo &ESI) {
+QualType ASTContext::getFunctionTypeWithExceptionSpec(
+QualType Orig, const FunctionProtoType::ExceptionSpecInfo &ESI) {
   // Might have some parens.
   if (auto *PT = dyn_cast(Orig))
-return Context.getParenType(
-getFunctionTypeWithExceptionSpec(Context, PT->getInnerType(), ESI));
+return getParenType(
+getFunctionTypeWithExceptionSpec(PT->getInnerType(), ESI));
 
   // Might have a calling-convention attribute.
   if (auto *AT = dyn_cast(Orig))
-return Context.getAttributedType(
+return getAttributedType(
 AT->getAttrKind(),
-getFunctionTypeWithExceptionSpec(Context, AT->getModifiedType(), ESI),
-getFunctionTypeWithExceptionSpec(Context, AT->getEquivalentType(),
- ESI));
+getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI),
+getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI));
 
   // Anything else must be a function type. Rebuild it with the new exception
   // specification.
   const FunctionProtoType *Proto = cast(Orig);
-  return Context.getFunctionType(
+  return getFunctionType(
   Proto->getReturnType(), Proto->getParamTypes(),
   Proto->getExtProtoInfo().withExceptionSpec(ESI));
 }
 
 bool ASTContext::hasSameFunctionTypeIgnoringExceptionSpec(QualType T,
   QualType U) {
   return hasSameType(T, U) ||
  (getLangOpts().CPlusPlus17 &&
-  hasSameType(getFunctionTypeWithExceptionSpec(*this, T, EST_None),
-  getFunctionTypeWithExceptionSpec(*this, U, EST_None)));
+  hasSameType(getFunctionTypeWithExceptionSpec(T, EST_None),
+  getFunctionTypeWithExceptionSpec(U, EST_None)));
 }
 
 void ASTContext::adjustExceptionSpec(
 FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI,
 bool AsWritten) {
   // Update the type.
   QualType Updated =
-  getFunctionTypeWithExceptionSpec(*this, FD->getType(), ESI);
+  getFunctionTypeWithExceptionSpec(FD->getType(), ESI);
   FD->setType(Updated);
 
   if (!AsWritten)
@@ -2630,7 +2628,7 @@
 // If the type and the type-as-written differ, we may need to update
 // the type-as-written too.
 if (TSInfo->getType() != FD->getType())
-  Updated = getFunctionTypeWithExceptionSpec(*this, TSInfo->getType(), ESI);
+  Updated = getFunctionTypeWithExceptionSpec(TSInfo->getType(), ESI);
 
 // FIXME: When we get proper type location information for exceptions,
 // we'll also have to rebuild the TypeSourceInfo. For now, we just patch
Index: lib/Sema/SemaOverload.cpp
===
--- lib/Sema/SemaOverload.cpp
+++ lib/Sema/SemaOverload.cpp
@@ -1475,10 +1475,8 @@
 const auto *ToFPT = cast(ToFn);
 if (FromFPT->isNothrow(Context) && !ToFPT->isNothrow(Context)) {

[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2018-01-05 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

Should this be backported to Clang 6?  Not sure how widespread a problem this 
is in practice (it hit me with LibreOffice).


Repository:
  rC Clang

https://reviews.llvm.org/D40720



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


[PATCH] D16632: clang-cl: Take dllexport from original function decl into account

2018-03-07 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 137374.
sberg added a comment.

Turns out DLLAttr-inherited-from-class is only added to members during 
Sema::CheckCompletedClass -> Sema::checkClassLevelDLLAttribute, when friend 
re-decls of those members may already have been created.


https://reviews.llvm.org/D16632

Files:
  clang/lib/Sema/SemaDeclCXX.cpp
  clang/test/CodeGenCXX/dllexport.cpp


Index: clang/test/CodeGenCXX/dllexport.cpp
===
--- clang/test/CodeGenCXX/dllexport.cpp
+++ clang/test/CodeGenCXX/dllexport.cpp
@@ -290,6 +290,16 @@
 __declspec(dllexport) void friend1() {}
   void friend2() {}
 
+// MSC-DAG: define dso_local dllexport void @"\01?func@Befriended@@SAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_ZN10Befriended4funcEv()
+struct __declspec(dllexport) Befriended {
+  static void func();
+  struct Befriending {
+friend void Befriended::func();
+  };
+};
+void Befriended::func() {}
+
 // Implicit declarations can be redeclared with dllexport.
 // MSC-DAG: define dso_local dllexport noalias i8* 
@"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
 // GNU-DAG: define dso_local dllexport noalias i8* @_Znw{{[yj]}}(
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -5688,6 +5688,21 @@
   cast(ClassAttr->clone(getASTContext()));
   NewAttr->setInherited(true);
   Member->addAttr(NewAttr);
+
+  if (MD) {
+// Propagate DLLAttr to friend re-declarations of MD that have already
+// been constructed.
+for (FunctionDecl *FD = MD->getMostRecentDecl(); FD;
+ FD = FD->getPreviousDecl()) {
+  if (FD->getFriendObjectKind() == Decl::FOK_None)
+continue;
+  assert(!getDLLAttr(FD) &&
+ "friend re-decl should not already have a DLLAttr");
+  NewAttr = cast(ClassAttr->clone(getASTContext()));
+  NewAttr->setInherited(true);
+  FD->addAttr(NewAttr);
+}
+  }
 }
   }
 


Index: clang/test/CodeGenCXX/dllexport.cpp
===
--- clang/test/CodeGenCXX/dllexport.cpp
+++ clang/test/CodeGenCXX/dllexport.cpp
@@ -290,6 +290,16 @@
 __declspec(dllexport) void friend1() {}
   void friend2() {}
 
+// MSC-DAG: define dso_local dllexport void @"\01?func@Befriended@@SAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_ZN10Befriended4funcEv()
+struct __declspec(dllexport) Befriended {
+  static void func();
+  struct Befriending {
+friend void Befriended::func();
+  };
+};
+void Befriended::func() {}
+
 // Implicit declarations can be redeclared with dllexport.
 // MSC-DAG: define dso_local dllexport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
 // GNU-DAG: define dso_local dllexport noalias i8* @_Znw{{[yj]}}(
Index: clang/lib/Sema/SemaDeclCXX.cpp
===
--- clang/lib/Sema/SemaDeclCXX.cpp
+++ clang/lib/Sema/SemaDeclCXX.cpp
@@ -5688,6 +5688,21 @@
   cast(ClassAttr->clone(getASTContext()));
   NewAttr->setInherited(true);
   Member->addAttr(NewAttr);
+
+  if (MD) {
+// Propagate DLLAttr to friend re-declarations of MD that have already
+// been constructed.
+for (FunctionDecl *FD = MD->getMostRecentDecl(); FD;
+ FD = FD->getPreviousDecl()) {
+  if (FD->getFriendObjectKind() == Decl::FOK_None)
+continue;
+  assert(!getDLLAttr(FD) &&
+ "friend re-decl should not already have a DLLAttr");
+  NewAttr = cast(ClassAttr->clone(getASTContext()));
+  NewAttr->setInherited(true);
+  FD->addAttr(NewAttr);
+}
+  }
 }
   }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D16632: clang-cl: Take dllexport from original function decl into account

2018-03-07 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL326990: Propagate DLLAttr to friend re-declarations of 
member functions (authored by sberg, committed by ).
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D16632?vs=137374&id=137548#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D16632

Files:
  cfe/trunk/lib/Sema/SemaDeclCXX.cpp
  cfe/trunk/test/CodeGenCXX/dllexport.cpp


Index: cfe/trunk/test/CodeGenCXX/dllexport.cpp
===
--- cfe/trunk/test/CodeGenCXX/dllexport.cpp
+++ cfe/trunk/test/CodeGenCXX/dllexport.cpp
@@ -290,6 +290,16 @@
 __declspec(dllexport) void friend1() {}
   void friend2() {}
 
+// MSC-DAG: define dso_local dllexport void @"\01?func@Befriended@@SAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_ZN10Befriended4funcEv()
+struct __declspec(dllexport) Befriended {
+  static void func();
+  struct Befriending {
+friend void Befriended::func();
+  };
+};
+void Befriended::func() {}
+
 // Implicit declarations can be redeclared with dllexport.
 // MSC-DAG: define dso_local dllexport noalias i8* 
@"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
 // GNU-DAG: define dso_local dllexport noalias i8* @_Znw{{[yj]}}(
Index: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
===
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp
@@ -5685,6 +5685,21 @@
   cast(ClassAttr->clone(getASTContext()));
   NewAttr->setInherited(true);
   Member->addAttr(NewAttr);
+
+  if (MD) {
+// Propagate DLLAttr to friend re-declarations of MD that have already
+// been constructed.
+for (FunctionDecl *FD = MD->getMostRecentDecl(); FD;
+ FD = FD->getPreviousDecl()) {
+  if (FD->getFriendObjectKind() == Decl::FOK_None)
+continue;
+  assert(!getDLLAttr(FD) &&
+ "friend re-decl should not already have a DLLAttr");
+  NewAttr = cast(ClassAttr->clone(getASTContext()));
+  NewAttr->setInherited(true);
+  FD->addAttr(NewAttr);
+}
+  }
 }
   }
 


Index: cfe/trunk/test/CodeGenCXX/dllexport.cpp
===
--- cfe/trunk/test/CodeGenCXX/dllexport.cpp
+++ cfe/trunk/test/CodeGenCXX/dllexport.cpp
@@ -290,6 +290,16 @@
 __declspec(dllexport) void friend1() {}
   void friend2() {}
 
+// MSC-DAG: define dso_local dllexport void @"\01?func@Befriended@@SAXXZ"()
+// GNU-DAG: define dso_local dllexport void @_ZN10Befriended4funcEv()
+struct __declspec(dllexport) Befriended {
+  static void func();
+  struct Befriending {
+friend void Befriended::func();
+  };
+};
+void Befriended::func() {}
+
 // Implicit declarations can be redeclared with dllexport.
 // MSC-DAG: define dso_local dllexport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"(
 // GNU-DAG: define dso_local dllexport noalias i8* @_Znw{{[yj]}}(
Index: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
===
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp
@@ -5685,6 +5685,21 @@
   cast(ClassAttr->clone(getASTContext()));
   NewAttr->setInherited(true);
   Member->addAttr(NewAttr);
+
+  if (MD) {
+// Propagate DLLAttr to friend re-declarations of MD that have already
+// been constructed.
+for (FunctionDecl *FD = MD->getMostRecentDecl(); FD;
+ FD = FD->getPreviousDecl()) {
+  if (FD->getFriendObjectKind() == Decl::FOK_None)
+continue;
+  assert(!getDLLAttr(FD) &&
+ "friend re-decl should not already have a DLLAttr");
+  NewAttr = cast(ClassAttr->clone(getASTContext()));
+  NewAttr->setInherited(true);
+  FD->addAttr(NewAttr);
+}
+  }
 }
   }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D52400: Improve -Wshadow warnings with enumerators

2018-10-16 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

doesnt this make -Wshadow more aggressive for enumerators than for other 
entities?

  ~ cat test17.cc
  struct S1;
  struct S2;
  struct S3 {
void S1();
enum { S2 };
  };
  
  ~ llvm/inst/bin/clang++ -fsyntax-only -Wshadow test17.cc 
  test17.cc:5:10: warning: declaration shadows a variable in the global 
namespace
[-Wshadow]
enum { S2 };
   ^
  test17.cc:2:8: note: previous declaration is here
  struct S2;
 ^
  1 warning generated.

warns about enumerator S2 but not about similar function S1

(ran into such a new -Wshadow while compiling LibreOffice)


https://reviews.llvm.org/D52400



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


[PATCH] D52400: Improve -Wshadow warnings with enumerators

2018-10-17 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

In https://reviews.llvm.org/D52400#1266341, @aaron.ballman wrote:

> In https://reviews.llvm.org/D52400#1266307, @sberg wrote:
>
> >
>


[...]

> Then again, this is a case where you don't get any error but you do get a 
> silent behavioral ambiguity without the current enumerator shadow diagnostic:
> 
>   struct S1;
>   struct S2;
>   struct S3 {
> void S1();
> enum { S2 };
>   
> void f(decltype(S2) s);
>   };
> 
> 
> So there are cases where this behavior can be somewhat useful.

but decltype(S2) is a syntax error when S2 names a struct type, no?

>> (ran into such a new -Wshadow while compiling LibreOffice)
> 
> Was it a frequent/annoying occurrence?

there was less than 20 cases overall. about half were "good" warnings about 
clashing enumerators from different non-scoped enums. the others were 
"unhelpful" ones about clashes with class names, two of them in stable 
interface code that cant be changed (so would need ugly #pragma clang warning 
decorations), one of them even about entities in unrelated include files, so 
whether a warning is emitted depends on the order in which the files happen to 
get included in a TU

(and in any case, "declaration shadows a variable" sounds wrong when the 
shadowed entity is a class type. thats why I thought something is not quite 
right with this new code yet)


https://reviews.llvm.org/D52400



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


[PATCH] D52400: Improve -Wshadow warnings with enumerators

2018-10-23 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

> I've silenced this scenario in r344898, thank you for raising the issue!

thanks! works fine for me


https://reviews.llvm.org/D52400



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


[PATCH] D55741: Implementation Feature Test Macros for P0722R3

2019-01-16 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

One problem I found with the macro `__cpp_impl_destroying_delete` not being 
conditional on language version is the following: Recent GCC trunk (since 
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=76b94d4ba654e9af1882865933343d11f5c3b18b
 "Implement P0722R3, destroying operator delete.") contains

  #if __cpp_impl_destroying_delete
  #define __cpp_lib_destroying_delete 201806L
  namespace std
  {
struct destroying_delete_t
{
  explicit destroying_delete_t() = default;
};
inline constexpr destroying_delete_t destroying_delete{};
  }
  #endif // destroying delete

at "top-level" (i.e., not in a C++20-only `#if` or similar) in 
`libstdc++-v3/libsupc++/new`.  That means that when using Clang against that 
GCC toolchain, `#include ` in C++03 mode will cause `error: unknown type 
name 'constexpr'`.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D55741/new/

https://reviews.llvm.org/D55741



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


[PATCH] D53974: [clang-tidy] new checker: bugprone-too-small-loop-variable

2018-11-01 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

> I run the new checker on LibreOffice project. I found ~25 false positives, 
> which seems small enough to me. This false positives can be supressed easily.

Do you have a link to such a false positive and how it got suppressed in the 
LibreOffice code base?  (If those are included in the referenced 
https://cgit.freedesktop.org/libreoffice/core/commit/?id=26ccd00bc96c585b7065af0dcce246b5bfaae5e1,
 I failed to spot them.)


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D53974



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


[PATCH] D60760: Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO

2019-04-16 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added reviewers: filcab, marxin, rsmith.
Herald added subscribers: llvm-commits, Sanitizers, cfe-commits, kristof.beyls, 
javed.absar, kubamracek.
Herald added projects: clang, Sanitizers, LLVM.

This follows up after b7692bc3e9ad2691fc07261904b88fb15f30696b 
 "[UBSan] 
Fix
isDerivedFromAtOffset on iOS ARM64" fixed the RTTI comparison in
isDerivedFromAtOffset on just one platform and then
a25a2c7c9a7e1e328a5bd8274d2d86b1fadc4692 
 "Always 
compare C++ typeinfo (based on
libstdc++ implementation)" extended that fix to more platforms.

But there is another RTTI comparison for -fsanitize=function generated in
clang's CodeGenFunction::EmitCall as just a pointer comparison.  For
SANITIZER_NON_UNIQUE_TYPEINFO platforms this needs to be extended to also do
string comparison.  For that, __ubsan_handle_function_type_mismatch[_abort]
takes the two std::type_info pointers as additional parameters now, checks them
internally for potential equivalence, and returns without reporting failure if
they turn out to be equivalent after all.  (NORETURN needed to be dropped from
the _abort variant for that.)  Also these functions depend on ABI-specific RTTI
now, so needed to be moved from plain UBSAN_SOURCES (ubsan_handlers.h/cc) to
UBSAN_CXXABI_SOURCES (ubsan_handlers_cxx.h/cc), but as -fsanitize=function is
only supported in C++ mode that's not a problem.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D60760

Files:
  clang/lib/CodeGen/CGExpr.cpp
  compiler-rt/lib/ubsan/ubsan_handlers.cc
  compiler-rt/lib/ubsan/ubsan_handlers.h
  compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc
  compiler-rt/lib/ubsan/ubsan_handlers_cxx.h
  compiler-rt/lib/ubsan/ubsan_type_hash.h
  compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc
  compiler-rt/lib/ubsan/ubsan_type_hash_win.cc

Index: compiler-rt/lib/ubsan/ubsan_type_hash_win.cc
===
--- compiler-rt/lib/ubsan/ubsan_type_hash_win.cc
+++ compiler-rt/lib/ubsan/ubsan_type_hash_win.cc
@@ -77,4 +77,9 @@
  "");
 }
 
+bool __ubsan::checkTypeInfoEquality(const std::type_info *,
+const std::type_info *) {
+  return false;
+}
+
 #endif  // CAN_SANITIZE_UB && SANITIZER_WINDOWS
Index: compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc
===
--- compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc
+++ compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc
@@ -117,9 +117,7 @@
   const abi::__class_type_info *Base,
   sptr Offset) {
   if (Derived->__type_name == Base->__type_name ||
-  (SANITIZER_NON_UNIQUE_TYPEINFO &&
-   Derived->__type_name[0] != '*' &&
-   !internal_strcmp(Derived->__type_name, Base->__type_name)))
+  __ubsan::checkTypeInfoEquality(Derived, Base))
 return Offset == 0;
 
   if (const abi::__si_class_type_info *SI =
@@ -258,4 +256,13 @@
  ObjectType ? ObjectType->__type_name : "");
 }
 
+bool __ubsan::checkTypeInfoEquality(const void *TypeInfo1,
+const void *TypeInfo2) {
+  auto TI1 = static_cast(TypeInfo1);
+  auto TI2 = static_cast(TypeInfo2);
+  return SANITIZER_NON_UNIQUE_TYPEINFO && TI1->__type_name[0] != '*' &&
+ TI2->__type_name[0] != '*' &&
+ !internal_strcmp(TI1->__type_name, TI2->__type_name);
+}
+
 #endif  // CAN_SANITIZE_UB && !SANITIZER_WINDOWS
Index: compiler-rt/lib/ubsan/ubsan_type_hash.h
===
--- compiler-rt/lib/ubsan/ubsan_type_hash.h
+++ compiler-rt/lib/ubsan/ubsan_type_hash.h
@@ -64,6 +64,10 @@
 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
 HashValue __ubsan_vptr_type_cache[VptrTypeCacheSize];
 
+/// \brief Do whatever is required by the ABI to check for std::type_info
+/// equivalence beyond simple pointer comparison.
+bool checkTypeInfoEquality(const void *TypeInfo1, const void *TypeInfo2);
+
 } // namespace __ubsan
 
 #endif // UBSAN_TYPE_HASH_H
Index: compiler-rt/lib/ubsan/ubsan_handlers_cxx.h
===
--- compiler-rt/lib/ubsan/ubsan_handlers_cxx.h
+++ compiler-rt/lib/ubsan/ubsan_handlers_cxx.h
@@ -33,6 +33,21 @@
 extern "C" SANITIZER_INTERFACE_ATTRIBUTE
 void __ubsan_handle_dynamic_type_cache_miss_abort(
   DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
+
+struct FunctionTypeMismatchData {
+  SourceLocation Loc;
+  const TypeDescriptor &Type;
+};
+
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE void
+__ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data,
+  ValueHandle Val, ValueHandle calleeRTTI,
+  ValueHandle fnRTTI);
+extern "C" SA

[PATCH] D60760: Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO

2019-04-16 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg marked an inline comment as done.
sberg added inline comments.



Comment at: compiler-rt/lib/ubsan/ubsan_type_hash_itanium.cc:264
+  return SANITIZER_NON_UNIQUE_TYPEINFO && TI1->__type_name[0] != '*' &&
+ TI2->__type_name[0] != '*' &&
+ !internal_strcmp(TI1->__type_name, TI2->__type_name);

My understanding of that GCC * prefix hack is that would should check 
symmetrically for both type_infos (which is different how isDerivedFromAtOffset 
above did it in the past)?


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60760/new/

https://reviews.llvm.org/D60760



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


[PATCH] D60760: Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO

2019-04-23 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

friendly ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60760/new/

https://reviews.llvm.org/D60760



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


[PATCH] D60760: Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO

2019-05-01 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rL359759: Adapt -fsanitize=function to 
SANITIZER_NON_UNIQUE_TYPEINFO (authored by sberg, committed by ).
Herald added a subscriber: delcypher.

Changed prior to commit:
  https://reviews.llvm.org/D60760?vs=195319&id=197706#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60760/new/

https://reviews.llvm.org/D60760

Files:
  cfe/trunk/lib/CodeGen/CGExpr.cpp
  compiler-rt/trunk/lib/ubsan/ubsan_handlers.cc
  compiler-rt/trunk/lib/ubsan/ubsan_handlers.h
  compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
  compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h
  compiler-rt/trunk/lib/ubsan/ubsan_type_hash.h
  compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc
  compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc

Index: cfe/trunk/lib/CodeGen/CGExpr.cpp
===
--- cfe/trunk/lib/CodeGen/CGExpr.cpp
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp
@@ -4672,7 +4672,8 @@
   llvm::Constant *StaticData[] = {EmitCheckSourceLocation(E->getBeginLoc()),
   EmitCheckTypeDescriptor(CalleeType)};
   EmitCheck(std::make_pair(CalleeRTTIMatch, SanitizerKind::Function),
-SanitizerHandler::FunctionTypeMismatch, StaticData, CalleePtr);
+SanitizerHandler::FunctionTypeMismatch, StaticData,
+{CalleePtr, CalleeRTTI, FTRTTIConst});
 
   Builder.CreateBr(Cont);
   EmitBlock(Cont);
Index: compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc
===
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash_itanium.cc
@@ -117,9 +117,7 @@
   const abi::__class_type_info *Base,
   sptr Offset) {
   if (Derived->__type_name == Base->__type_name ||
-  (SANITIZER_NON_UNIQUE_TYPEINFO &&
-   Derived->__type_name[0] != '*' &&
-   !internal_strcmp(Derived->__type_name, Base->__type_name)))
+  __ubsan::checkTypeInfoEquality(Derived, Base))
 return Offset == 0;
 
   if (const abi::__si_class_type_info *SI =
@@ -258,4 +256,13 @@
  ObjectType ? ObjectType->__type_name : "");
 }
 
+bool __ubsan::checkTypeInfoEquality(const void *TypeInfo1,
+const void *TypeInfo2) {
+  auto TI1 = static_cast(TypeInfo1);
+  auto TI2 = static_cast(TypeInfo2);
+  return SANITIZER_NON_UNIQUE_TYPEINFO && TI1->__type_name[0] != '*' &&
+ TI2->__type_name[0] != '*' &&
+ !internal_strcmp(TI1->__type_name, TI2->__type_name);
+}
+
 #endif  // CAN_SANITIZE_UB && !SANITIZER_WINDOWS
Index: compiler-rt/trunk/lib/ubsan/ubsan_handlers.h
===
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers.h
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers.h
@@ -168,15 +168,6 @@
 /// Handle a builtin called in an invalid way.
 RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data)
 
-struct FunctionTypeMismatchData {
-  SourceLocation Loc;
-  const TypeDescriptor &Type;
-};
-
-RECOVERABLE(function_type_mismatch,
-FunctionTypeMismatchData *Data,
-ValueHandle Val)
-
 struct NonNullReturnData {
   SourceLocation AttrLoc;
 };
Index: compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc
===
--- compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc
+++ compiler-rt/trunk/lib/ubsan/ubsan_type_hash_win.cc
@@ -77,4 +77,9 @@
  "");
 }
 
+bool __ubsan::checkTypeInfoEquality(const std::type_info *,
+const std::type_info *) {
+  return false;
+}
+
 #endif  // CAN_SANITIZE_UB && SANITIZER_WINDOWS
Index: compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
===
--- compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
+++ compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
@@ -156,6 +156,51 @@
 Diag(Loc, DL_Note, ET, "check failed in %0, vtable located in %1")
 << SrcModule << DstModule;
 }
+
+static bool handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
+   ValueHandle Function,
+   ValueHandle calleeRTTI,
+   ValueHandle fnRTTI, ReportOptions Opts) {
+  if (checkTypeInfoEquality(reinterpret_cast(calleeRTTI),
+reinterpret_cast(fnRTTI)))
+return false;
+
+  SourceLocation CallLoc = Data->Loc.acquire();
+  ErrorType ET = ErrorType::FunctionTypeMismatch;
+
+  if (ignoreReport(CallLoc, Opts, ET))
+return true;
+
+  ScopedReport R(Opts, CallLoc, ET);
+
+  SymbolizedStackHolder FLoc(getSymbolizedLoca

[PATCH] D60760: Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO

2019-05-02 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

In D60760#1487342 , @lebedev.ri wrote:

> Did this get reviewed?


I didn't get any responses at all, so decided to push it anyway.


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60760/new/

https://reviews.llvm.org/D60760



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


[PATCH] D60760: Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO

2019-05-02 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

Added missing tests at https://reviews.llvm.org/D61479 "Add tests for 'Adapt 
-fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO'".


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60760/new/

https://reviews.llvm.org/D60760



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


[PATCH] D58056: Look through typedefs in getFunctionTypeWithExceptionSpec

2019-02-11 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added a reviewer: rsmith.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

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


Repository:
  rC Clang

https://reviews.llvm.org/D58056

Files:
  clang/lib/AST/ASTContext.cpp
  clang/test/AST/function-alias.cpp


Index: clang/test/AST/function-alias.cpp
===
--- /dev/null
+++ clang/test/AST/function-alias.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s
+
+// Verify that ASTContext::getFunctionTypeWithExceptionSpec (called through
+// ASTContext::hasSameFunctionTypeIgnoringExceptionSpec from
+// ExprEvaluatorBase::handleCallExpr in lib/AST/ExprConstant.cpp) does not 
crash
+// for a type alias.
+
+constexpr int f() noexcept { return 0; }
+
+using F = int();
+
+constexpr int g(F * p) { return p(); }
+
+constexpr int n = g(f);
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2771,7 +2771,7 @@
 
   // Anything else must be a function type. Rebuild it with the new exception
   // specification.
-  const auto *Proto = cast(Orig);
+  const auto *Proto = Orig->getAs();
   return getFunctionType(
   Proto->getReturnType(), Proto->getParamTypes(),
   Proto->getExtProtoInfo().withExceptionSpec(ESI));


Index: clang/test/AST/function-alias.cpp
===
--- /dev/null
+++ clang/test/AST/function-alias.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s
+
+// Verify that ASTContext::getFunctionTypeWithExceptionSpec (called through
+// ASTContext::hasSameFunctionTypeIgnoringExceptionSpec from
+// ExprEvaluatorBase::handleCallExpr in lib/AST/ExprConstant.cpp) does not crash
+// for a type alias.
+
+constexpr int f() noexcept { return 0; }
+
+using F = int();
+
+constexpr int g(F * p) { return p(); }
+
+constexpr int n = g(f);
Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2771,7 +2771,7 @@
 
   // Anything else must be a function type. Rebuild it with the new exception
   // specification.
-  const auto *Proto = cast(Orig);
+  const auto *Proto = Orig->getAs();
   return getFunctionType(
   Proto->getReturnType(), Proto->getParamTypes(),
   Proto->getExtProtoInfo().withExceptionSpec(ESI));
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D58056: Look through typedefs in getFunctionTypeWithExceptionSpec

2019-02-11 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

The change itself should probably be uncontroversial (the bad cast had been 
there ever since getFunctionTypeWithExceptionSpec had been introduced with 
r221918), but I'm not sure about the test: It tests the relevant code somewhat 
indirectly; is it fine in clang/test/AST/?; or is such a test even overkill?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D58056/new/

https://reviews.llvm.org/D58056



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


[PATCH] D58056: Look through typedefs in getFunctionTypeWithExceptionSpec

2019-02-13 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was not accepted when it landed; it landed in state "Needs 
Review".
This revision was automatically updated to reflect the committed changes.
Closed by commit rC353931: Look through typedefs in 
getFunctionTypeWithExceptionSpec (authored by sberg, committed by ).

Changed prior to commit:
  https://reviews.llvm.org/D58056?vs=186269&id=186604#toc

Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D58056/new/

https://reviews.llvm.org/D58056

Files:
  lib/AST/ASTContext.cpp
  test/AST/function-alias.cpp


Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -2771,7 +2771,7 @@
 
   // Anything else must be a function type. Rebuild it with the new exception
   // specification.
-  const auto *Proto = cast(Orig);
+  const auto *Proto = Orig->getAs();
   return getFunctionType(
   Proto->getReturnType(), Proto->getParamTypes(),
   Proto->getExtProtoInfo().withExceptionSpec(ESI));
Index: test/AST/function-alias.cpp
===
--- test/AST/function-alias.cpp
+++ test/AST/function-alias.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s
+
+// Verify that ASTContext::getFunctionTypeWithExceptionSpec (called through
+// ASTContext::hasSameFunctionTypeIgnoringExceptionSpec from
+// ExprEvaluatorBase::handleCallExpr in lib/AST/ExprConstant.cpp) does not 
crash
+// for a type alias.
+
+constexpr int f() noexcept { return 0; }
+
+using F = int();
+
+constexpr int g(F * p) { return p(); }
+
+constexpr int n = g(f);


Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -2771,7 +2771,7 @@
 
   // Anything else must be a function type. Rebuild it with the new exception
   // specification.
-  const auto *Proto = cast(Orig);
+  const auto *Proto = Orig->getAs();
   return getFunctionType(
   Proto->getReturnType(), Proto->getParamTypes(),
   Proto->getExtProtoInfo().withExceptionSpec(ESI));
Index: test/AST/function-alias.cpp
===
--- test/AST/function-alias.cpp
+++ test/AST/function-alias.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++17 -fsyntax-only %s
+
+// Verify that ASTContext::getFunctionTypeWithExceptionSpec (called through
+// ASTContext::hasSameFunctionTypeIgnoringExceptionSpec from
+// ExprEvaluatorBase::handleCallExpr in lib/AST/ExprConstant.cpp) does not crash
+// for a type alias.
+
+constexpr int f() noexcept { return 0; }
+
+using F = int();
+
+constexpr int g(F * p) { return p(); }
+
+constexpr int n = g(f);
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D58056: Look through typedefs in getFunctionTypeWithExceptionSpec

2019-02-13 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

committed for now to get the crash fixed; if there are issues with the test 
they can be addressed later


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D58056/new/

https://reviews.llvm.org/D58056



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


[PATCH] D61479: Finish "Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO"

2019-07-15 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 209865.
sberg added a comment.

- Disallowed -fsanitize=function in combination with -fsanitize-minimal-runtime 
now.

- Left the ubsan test's RUN lines and \#include magic as-is, if there's no 
clearly better way to avoid this unfortunate complexity.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61479/new/

https://reviews.llvm.org/D61479

Files:
  clang/docs/UndefinedBehaviorSanitizer.rst
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  clang/lib/Driver/SanitizerArgs.cpp
  clang/test/CodeGen/ubsan-function.cpp
  clang/test/Driver/fsanitize.c
  compiler-rt/lib/ubsan/ubsan_handlers_cxx.cc
  compiler-rt/lib/ubsan/ubsan_handlers_cxx.h
  compiler-rt/lib/ubsan/ubsan_interface.inc
  compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp

Index: compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
===
--- compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
+++ compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
@@ -1,11 +1,53 @@
-// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t
-// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx -DDETERMINE_UNIQUE %s -o %t-unique
+// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -DSHARED_LIB -fPIC -shared -o %t-so.so
+// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t %t-so.so
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK $(%run %t-unique UNIQUE)
 // Verify that we can disable symbolization if needed:
-// RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
+// RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM $(%run %t-unique NOSYM-UNIQUE)
 // XFAIL: windows-msvc
 // Unsupported function flag
 // UNSUPPORTED: openbsd
 
+#ifdef DETERMINE_UNIQUE
+
+#include 
+
+#include "../../../../../lib/sanitizer_common/sanitizer_platform.h"
+
+int main(int, char **argv) {
+  if (!SANITIZER_NON_UNIQUE_TYPEINFO)
+std::cout << "--check-prefix=" << argv[1];
+}
+
+#else
+
+struct Shared {};
+using FnShared = void (*)(Shared *);
+FnShared getShared();
+
+struct __attribute__((visibility("hidden"))) Hidden {};
+using FnHidden = void (*)(Hidden *);
+FnHidden getHidden();
+
+namespace {
+struct Private {};
+} // namespace
+using FnPrivate = void (*)(void *);
+FnPrivate getPrivate();
+
+#ifdef SHARED_LIB
+
+void fnShared(Shared *) {}
+FnShared getShared() { return fnShared; }
+
+void fnHidden(Hidden *) {}
+FnHidden getHidden() { return fnHidden; }
+
+void fnPrivate(Private *) {}
+FnPrivate getPrivate() { return reinterpret_cast(fnPrivate); }
+
+#else
+
 #include 
 
 void f() {}
@@ -64,12 +106,31 @@
   p2(0);
 }
 
+void check_cross_dso() {
+  getShared()(nullptr);
+
+  // UNIQUE: function.cpp:[[@LINE+2]]:3: runtime error: call to function fnHidden(Hidden*) through pointer to incorrect function type 'void (*)(Hidden *)'
+  // NOSYM-UNIQUE: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(Hidden *)'
+  getHidden()(nullptr);
+
+  // TODO: Unlike GCC, Clang fails to prefix the typeinfo name for the function
+  // type with "*", so this erroneously only fails for "*UNIQUE":
+  // UNIQUE: function.cpp:[[@LINE+2]]:3: runtime error: call to function fnPrivate((anonymous namespace)::Private*) through pointer to incorrect function type 'void (*)((anonymous namespace)::Private *)'
+  // NOSYM-UNIQUE: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)((anonymous namespace)::Private *)'
+  reinterpret_cast(getPrivate())(nullptr);
+}
+
 int main(void) {
   make_valid_call();
   make_invalid_call();
   check_noexcept_calls();
+  check_cross_dso();
   // Check that no more errors will be printed.
   // CHECK-NOT: runtime error: call to function
   // NOSYM-NOT: runtime error: call to function
   make_invalid_call();
 }
+
+#endif
+
+#endif
Index: compiler-rt/lib/ubsan/ubsan_interface.inc
===
--- compiler-rt/lib/ubsan/ubsan_interface.inc
+++ compiler-rt/lib/ubsan/ubsan_interface.inc
@@ -21,8 +21,8 @@
 INTERFACE_FUNCTION(__ubsan_handle_dynamic_type_cache_miss_abort)
 INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow)
 INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow_abort)
-INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch)
-INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_abort)
+INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1)
+INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1_abort)
 INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion)
 INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion_abort)
 INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin)
Index: compiler-rt/lib/ubsan/ubsan_handlers_cxx.h
===
--- compile

[PATCH] D61479: Finish "Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO"

2019-07-15 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL366186: Finish "Adapt -fsanitize=function to 
SANITIZER_NON_UNIQUE_TYPEINFO" (authored by sberg, committed by ).
Herald added a subscriber: delcypher.

Changed prior to commit:
  https://reviews.llvm.org/D61479?vs=209865&id=210025#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61479/new/

https://reviews.llvm.org/D61479

Files:
  cfe/trunk/docs/UndefinedBehaviorSanitizer.rst
  cfe/trunk/lib/CodeGen/CGExpr.cpp
  cfe/trunk/lib/CodeGen/CodeGenFunction.h
  cfe/trunk/lib/Driver/SanitizerArgs.cpp
  cfe/trunk/test/CodeGen/ubsan-function.cpp
  cfe/trunk/test/Driver/fsanitize.c
  compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.cc
  compiler-rt/trunk/lib/ubsan/ubsan_handlers_cxx.h
  compiler-rt/trunk/lib/ubsan/ubsan_interface.inc
  compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/Function/function.cpp

Index: compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/Function/function.cpp
===
--- compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/Function/function.cpp
+++ compiler-rt/trunk/test/ubsan/TestCases/TypeCheck/Function/function.cpp
@@ -1,11 +1,53 @@
-// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t
-// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx -DDETERMINE_UNIQUE %s -o %t-unique
+// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -DSHARED_LIB -fPIC -shared -o %t-so.so
+// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t %t-so.so
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK $(%run %t-unique UNIQUE)
 // Verify that we can disable symbolization if needed:
-// RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
+// RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM $(%run %t-unique NOSYM-UNIQUE)
 // XFAIL: windows-msvc
 // Unsupported function flag
 // UNSUPPORTED: openbsd
 
+#ifdef DETERMINE_UNIQUE
+
+#include 
+
+#include "../../../../../lib/sanitizer_common/sanitizer_platform.h"
+
+int main(int, char **argv) {
+  if (!SANITIZER_NON_UNIQUE_TYPEINFO)
+std::cout << "--check-prefix=" << argv[1];
+}
+
+#else
+
+struct Shared {};
+using FnShared = void (*)(Shared *);
+FnShared getShared();
+
+struct __attribute__((visibility("hidden"))) Hidden {};
+using FnHidden = void (*)(Hidden *);
+FnHidden getHidden();
+
+namespace {
+struct Private {};
+} // namespace
+using FnPrivate = void (*)(void *);
+FnPrivate getPrivate();
+
+#ifdef SHARED_LIB
+
+void fnShared(Shared *) {}
+FnShared getShared() { return fnShared; }
+
+void fnHidden(Hidden *) {}
+FnHidden getHidden() { return fnHidden; }
+
+void fnPrivate(Private *) {}
+FnPrivate getPrivate() { return reinterpret_cast(fnPrivate); }
+
+#else
+
 #include 
 
 void f() {}
@@ -64,12 +106,31 @@
   p2(0);
 }
 
+void check_cross_dso() {
+  getShared()(nullptr);
+
+  // UNIQUE: function.cpp:[[@LINE+2]]:3: runtime error: call to function fnHidden(Hidden*) through pointer to incorrect function type 'void (*)(Hidden *)'
+  // NOSYM-UNIQUE: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(Hidden *)'
+  getHidden()(nullptr);
+
+  // TODO: Unlike GCC, Clang fails to prefix the typeinfo name for the function
+  // type with "*", so this erroneously only fails for "*UNIQUE":
+  // UNIQUE: function.cpp:[[@LINE+2]]:3: runtime error: call to function fnPrivate((anonymous namespace)::Private*) through pointer to incorrect function type 'void (*)((anonymous namespace)::Private *)'
+  // NOSYM-UNIQUE: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)((anonymous namespace)::Private *)'
+  reinterpret_cast(getPrivate())(nullptr);
+}
+
 int main(void) {
   make_valid_call();
   make_invalid_call();
   check_noexcept_calls();
+  check_cross_dso();
   // Check that no more errors will be printed.
   // CHECK-NOT: runtime error: call to function
   // NOSYM-NOT: runtime error: call to function
   make_invalid_call();
 }
+
+#endif
+
+#endif
Index: compiler-rt/trunk/lib/ubsan/ubsan_interface.inc
===
--- compiler-rt/trunk/lib/ubsan/ubsan_interface.inc
+++ compiler-rt/trunk/lib/ubsan/ubsan_interface.inc
@@ -21,8 +21,8 @@
 INTERFACE_FUNCTION(__ubsan_handle_dynamic_type_cache_miss_abort)
 INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow)
 INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow_abort)
-INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch)
-INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_abort)
+INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1)
+INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1_abort)
 INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion)
 INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion_abort)
 INTERFACE_FUNCTION(__ubsan_handle_

[PATCH] D61479: Finish "Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO"

2019-07-15 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

eh, the summary here doesn't get updated from the actual git commit message :(

thanks for the reviews!


Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61479/new/

https://reviews.llvm.org/D61479



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


[PATCH] D66350: Rudimentary support for Doxygen \retval command

2019-08-16 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added a reviewer: gribozavr.
sberg added a project: clang.
Herald added a subscriber: cfe-commits.

...so that at least a preceding \param etc. that lacks a description gets a 
-Wdocumentation warning (instead of erroneously treating the \retval ... text 
as its paragraph).


Repository:
  rC Clang

https://reviews.llvm.org/D66350

Files:
  clang/include/clang/AST/CommentCommands.td
  clang/test/Sema/warn-documentation.cpp


Index: clang/test/Sema/warn-documentation.cpp
===
--- clang/test/Sema/warn-documentation.cpp
+++ clang/test/Sema/warn-documentation.cpp
@@ -288,6 +288,11 @@
 /// \param x2 Ccc.
 int test_param22(int x1, int x2, int x3);
 
+// expected-warning@+1 {{empty paragraph passed to '\param' command}}
+/// \param a
+/// \retval 0 Blah blah.
+int test_param23(int a);
+
 //===---
 // Test that we treat typedefs to some non-function types as functions for the
 // purposes of documentation comment parsing.
Index: clang/include/clang/AST/CommentCommands.td
===
--- clang/include/clang/AST/CommentCommands.td
+++ clang/include/clang/AST/CommentCommands.td
@@ -139,6 +139,7 @@
 def Pre: BlockCommand<"pre">;
 def Remark : BlockCommand<"remark">;
 def Remarks: BlockCommand<"remarks">;
+def Retval : BlockCommand<"retval">;
 def Sa : BlockCommand<"sa">;
 def See: BlockCommand<"see">;
 def Since  : BlockCommand<"since">;


Index: clang/test/Sema/warn-documentation.cpp
===
--- clang/test/Sema/warn-documentation.cpp
+++ clang/test/Sema/warn-documentation.cpp
@@ -288,6 +288,11 @@
 /// \param x2 Ccc.
 int test_param22(int x1, int x2, int x3);
 
+// expected-warning@+1 {{empty paragraph passed to '\param' command}}
+/// \param a
+/// \retval 0 Blah blah.
+int test_param23(int a);
+
 //===---
 // Test that we treat typedefs to some non-function types as functions for the
 // purposes of documentation comment parsing.
Index: clang/include/clang/AST/CommentCommands.td
===
--- clang/include/clang/AST/CommentCommands.td
+++ clang/include/clang/AST/CommentCommands.td
@@ -139,6 +139,7 @@
 def Pre: BlockCommand<"pre">;
 def Remark : BlockCommand<"remark">;
 def Remarks: BlockCommand<"remarks">;
+def Retval : BlockCommand<"retval">;
 def Sa : BlockCommand<"sa">;
 def See: BlockCommand<"see">;
 def Since  : BlockCommand<"since">;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D66350: Rudimentary support for Doxygen \retval command

2019-08-20 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL369345: Rudimentary support for Doxygen \retval command 
(authored by sberg, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D66350?vs=215599&id=216069#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D66350/new/

https://reviews.llvm.org/D66350

Files:
  cfe/trunk/include/clang/AST/CommentCommands.td
  cfe/trunk/test/Sema/warn-documentation.cpp


Index: cfe/trunk/include/clang/AST/CommentCommands.td
===
--- cfe/trunk/include/clang/AST/CommentCommands.td
+++ cfe/trunk/include/clang/AST/CommentCommands.td
@@ -139,6 +139,7 @@
 def Pre: BlockCommand<"pre">;
 def Remark : BlockCommand<"remark">;
 def Remarks: BlockCommand<"remarks">;
+def Retval : BlockCommand<"retval">;
 def Sa : BlockCommand<"sa">;
 def See: BlockCommand<"see">;
 def Since  : BlockCommand<"since">;
Index: cfe/trunk/test/Sema/warn-documentation.cpp
===
--- cfe/trunk/test/Sema/warn-documentation.cpp
+++ cfe/trunk/test/Sema/warn-documentation.cpp
@@ -288,6 +288,11 @@
 /// \param x2 Ccc.
 int test_param22(int x1, int x2, int x3);
 
+// expected-warning@+1 {{empty paragraph passed to '\param' command}}
+/// \param a
+/// \retval 0 Blah blah.
+int test_param23(int a);
+
 //===---
 // Test that we treat typedefs to some non-function types as functions for the
 // purposes of documentation comment parsing.


Index: cfe/trunk/include/clang/AST/CommentCommands.td
===
--- cfe/trunk/include/clang/AST/CommentCommands.td
+++ cfe/trunk/include/clang/AST/CommentCommands.td
@@ -139,6 +139,7 @@
 def Pre: BlockCommand<"pre">;
 def Remark : BlockCommand<"remark">;
 def Remarks: BlockCommand<"remarks">;
+def Retval : BlockCommand<"retval">;
 def Sa : BlockCommand<"sa">;
 def See: BlockCommand<"see">;
 def Since  : BlockCommand<"since">;
Index: cfe/trunk/test/Sema/warn-documentation.cpp
===
--- cfe/trunk/test/Sema/warn-documentation.cpp
+++ cfe/trunk/test/Sema/warn-documentation.cpp
@@ -288,6 +288,11 @@
 /// \param x2 Ccc.
 int test_param22(int x1, int x2, int x3);
 
+// expected-warning@+1 {{empty paragraph passed to '\param' command}}
+/// \param a
+/// \retval 0 Blah blah.
+int test_param23(int a);
+
 //===---
 // Test that we treat typedefs to some non-function types as functions for the
 // purposes of documentation comment parsing.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D61479: Finish "Adapt -fsanitize=function to SANITIZER_NON_UNIQUE_TYPEINFO"

2019-06-26 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a subscriber: cfe-commits.
sberg added a comment.

Any thoughts on this?  (cfe-commits had inadvertently been missing from 
subscribers, it touches clang as well as compiler-rt.)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D61479/new/

https://reviews.llvm.org/D61479



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


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

2018-04-17 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

It looks like this caused a clang-cl regression 
https://bugs.llvm.org/show_bug.cgi?id=37146 "clang-cl emits special functions 
for non-trivial C-structs ('__destructor_8') introduced for Objective-C".


Repository:
  rL LLVM

https://reviews.llvm.org/D41228



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


[PATCH] D45601: Warn on bool* to bool conversion

2018-04-17 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

A random data point from trying this patch on the LibreOffice code base:

- a little over 100 cases that are easily identified as false positives (many 
of the form "if (p) *p = ...")

- two or three cases that looked suspicious on first glance but turned out to 
be false positives too (but where the code apparently benefits from cleaning up)

- two cases of false positives that are awkward to silence (via "!= nullptr") 
in a way compatible with older C++ standards, as they are of the form "if (bool 
* p = ...)", and can be rewritten to "if (bool * p = ...; p != nullptr)" only 
for recent C++

- one false positive in system-provided /usr/include/qt5/QtCore/qstring.h

- no true positives found


https://reviews.llvm.org/D45601



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


[PATCH] D45112: [MS] Emit vftable thunks for functions with incomplete prototypes

2018-04-18 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

see https://bugs.llvm.org/show_bug.cgi?id=37161 "clang-cl triggers 
ASTContext::getASTRecordLayout Assertion `D && 'Cannot get layout of forward 
declarations!''" for what appears to be fallout from this change


Repository:
  rL LLVM

https://reviews.llvm.org/D45112



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


[PATCH] D68581: Include leading attributes in DeclStmt's SourceRange

2019-10-07 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added reviewers: aaron.ballman, rsmith, Nathan-Huckleberry.
Herald added a project: clang.

For a `DeclStmt` like

  [[maybe_unused]] int i;

`getBeginLoc()` returned the start of `int` instead of the start of `[[` (see 
http://lists.llvm.org/pipermail/cfe-dev/2019-September/063434.html "[cfe-dev] 
Poor DeclStmt source range with leading [[attributes]]?").

Is there a good way to write a test for this?


Repository:
  rC Clang

https://reviews.llvm.org/D68581

Files:
  clang/lib/Parse/ParseStmt.cpp


Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -220,6 +220,8 @@
 Decl =
 ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, Attrs);
   }
+  if (Attrs.Range.getBegin().isValid())
+  DeclStart = Attrs.Range.getBegin();
   return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
 }
 


Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -220,6 +220,8 @@
 Decl =
 ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, Attrs);
   }
+  if (Attrs.Range.getBegin().isValid())
+  DeclStart = Attrs.Range.getBegin();
   return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68581: Include leading attributes in DeclStmt's SourceRange

2019-10-10 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 224303.
sberg edited the summary of this revision.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68581/new/

https://reviews.llvm.org/D68581

Files:
  clang/lib/Parse/ParseStmt.cpp
  clang/test/AST/sourceranges.cpp


Index: clang/test/AST/sourceranges.cpp
===
--- clang/test/AST/sourceranges.cpp
+++ clang/test/AST/sourceranges.cpp
@@ -143,4 +143,14 @@
 new int{0};
   }
 }
+
+// CHECK-1Z: NamespaceDecl {{.*}} attributed_decl
+namespace attributed_decl {
+  void f() {
+// CHECK-1Z: DeclStmt {{.*}} 
+[[maybe_unused]] int i;
+// CHECK-1Z: DeclStmt {{.*}} 
+int __attribute__((unused)) j;
+  }
+}
 #endif
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -220,6 +220,8 @@
 Decl =
 ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, Attrs);
   }
+  if (Attrs.Range.getBegin().isValid())
+DeclStart = Attrs.Range.getBegin();
   return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
 }
 


Index: clang/test/AST/sourceranges.cpp
===
--- clang/test/AST/sourceranges.cpp
+++ clang/test/AST/sourceranges.cpp
@@ -143,4 +143,14 @@
 new int{0};
   }
 }
+
+// CHECK-1Z: NamespaceDecl {{.*}} attributed_decl
+namespace attributed_decl {
+  void f() {
+// CHECK-1Z: DeclStmt {{.*}} 
+[[maybe_unused]] int i;
+// CHECK-1Z: DeclStmt {{.*}} 
+int __attribute__((unused)) j;
+  }
+}
 #endif
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -220,6 +220,8 @@
 Decl =
 ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, Attrs);
   }
+  if (Attrs.Range.getBegin().isValid())
+DeclStart = Attrs.Range.getBegin();
   return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68581: Include leading attributes in DeclStmt's SourceRange

2019-10-14 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 224823.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68581/new/

https://reviews.llvm.org/D68581

Files:
  clang/lib/Parse/ParseStmt.cpp
  clang/test/AST/sourceranges.cpp


Index: clang/test/AST/sourceranges.cpp
===
--- clang/test/AST/sourceranges.cpp
+++ clang/test/AST/sourceranges.cpp
@@ -144,3 +144,18 @@
   }
 }
 #endif
+
+// CHECK: NamespaceDecl {{.*}} attributed_decl
+namespace attributed_decl {
+  void cpp11() {
+// CHECK: DeclStmt {{.*}} 
+int __attribute__((unused)) i;
+  }
+
+#if __cplusplus >= 201703L
+  void cpp17() {
+// CHECK-1Z: DeclStmt {{.*}} 
+[[maybe_unused]] int i;
+  }
+#endif
+}
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -220,6 +220,8 @@
 Decl =
 ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, Attrs);
   }
+  if (Attrs.Range.getBegin().isValid())
+DeclStart = Attrs.Range.getBegin();
   return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
 }
 


Index: clang/test/AST/sourceranges.cpp
===
--- clang/test/AST/sourceranges.cpp
+++ clang/test/AST/sourceranges.cpp
@@ -144,3 +144,18 @@
   }
 }
 #endif
+
+// CHECK: NamespaceDecl {{.*}} attributed_decl
+namespace attributed_decl {
+  void cpp11() {
+// CHECK: DeclStmt {{.*}} 
+int __attribute__((unused)) i;
+  }
+
+#if __cplusplus >= 201703L
+  void cpp17() {
+// CHECK-1Z: DeclStmt {{.*}} 
+[[maybe_unused]] int i;
+  }
+#endif
+}
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -220,6 +220,8 @@
 Decl =
 ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, Attrs);
   }
+  if (Attrs.Range.getBegin().isValid())
+DeclStart = Attrs.Range.getBegin();
   return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68581: Include leading attributes in DeclStmt's SourceRange

2019-10-17 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGdc3957ec215d: Include leading attributes in DeclStmt's 
SourceRange (authored by sberg).

Changed prior to commit:
  https://reviews.llvm.org/D68581?vs=224823&id=225397#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68581/new/

https://reviews.llvm.org/D68581

Files:
  clang/lib/Parse/ParseStmt.cpp
  clang/test/AST/sourceranges.cpp


Index: clang/test/AST/sourceranges.cpp
===
--- clang/test/AST/sourceranges.cpp
+++ clang/test/AST/sourceranges.cpp
@@ -92,6 +92,22 @@
 
 }; // namespace std
 
+// CHECK: NamespaceDecl {{.*}} attributed_decl
+namespace attributed_decl {
+  void f() {
+// CHECK: DeclStmt {{.*}} 
+[[maybe_unused]] int i1;
+// CHECK: DeclStmt {{.*}} 
+__attribute__((unused)) int i2;
+// CHECK: DeclStmt {{.*}} 
+int __attribute__((unused)) i3;
+// CHECK: DeclStmt {{.*}} <:{{.*}}, {{.*}}:[[@LINE+1]]:40>
+__declspec(dllexport) extern int i4;
+// CHECK: DeclStmt {{.*}} 
+extern int __declspec(dllexport) i5;
+  }
+}
+
 #if __cplusplus >= 201703L
 // CHECK-1Z: FunctionDecl {{.*}} construct_with_init_list
 std::map construct_with_init_list() {
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -220,6 +220,8 @@
 Decl =
 ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, Attrs);
   }
+  if (Attrs.Range.getBegin().isValid())
+DeclStart = Attrs.Range.getBegin();
   return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
 }
 


Index: clang/test/AST/sourceranges.cpp
===
--- clang/test/AST/sourceranges.cpp
+++ clang/test/AST/sourceranges.cpp
@@ -92,6 +92,22 @@
 
 }; // namespace std
 
+// CHECK: NamespaceDecl {{.*}} attributed_decl
+namespace attributed_decl {
+  void f() {
+// CHECK: DeclStmt {{.*}} 
+[[maybe_unused]] int i1;
+// CHECK: DeclStmt {{.*}} 
+__attribute__((unused)) int i2;
+// CHECK: DeclStmt {{.*}} 
+int __attribute__((unused)) i3;
+// CHECK: DeclStmt {{.*}} <:{{.*}}, {{.*}}:[[@LINE+1]]:40>
+__declspec(dllexport) extern int i4;
+// CHECK: DeclStmt {{.*}} 
+extern int __declspec(dllexport) i5;
+  }
+}
+
 #if __cplusplus >= 201703L
 // CHECK-1Z: FunctionDecl {{.*}} construct_with_init_list
 std::map construct_with_init_list() {
Index: clang/lib/Parse/ParseStmt.cpp
===
--- clang/lib/Parse/ParseStmt.cpp
+++ clang/lib/Parse/ParseStmt.cpp
@@ -220,6 +220,8 @@
 Decl =
 ParseDeclaration(DeclaratorContext::BlockContext, DeclEnd, Attrs);
   }
+  if (Attrs.Range.getBegin().isValid())
+DeclStart = Attrs.Range.getBegin();
   return Actions.ActOnDeclStmt(Decl, DeclStart, DeclEnd);
 }
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D68581: Include leading attributes in DeclStmt's SourceRange

2019-10-17 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg marked 2 inline comments as done.
sberg added inline comments.



Comment at: clang/test/AST/sourceranges.cpp:155
+
+#if __cplusplus >= 201703L
+  void cpp17() {

aaron.ballman wrote:
> Why is this guarded on C++17? `[[maybe_unused]]` is supported in every 
> language mode used by this test (it generates a warning, but we're 
> FileCheck'ing so that's fine -- but you could use `[[deprecated("")]]` 
> instead if you want).
> 
> Additionally, I'd appreciate one more test case testing a `__declspec` 
> attribute as well, to make sure we're handling that properly as well.
Oh, didn't know that [[maybe_unused]] would also be accepted in pre-C++17  
modes (I was somehow under the false impression that this file would be 
processed as -std=c++11 by default, where [[deprecated("")]] wouldn't have 
worked either).
Testing both __attribute__ and __declspec at both the start and in the middle 
of the stmt now.  (One caveat with __declspec is that its location resolves to 
, though.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68581/new/

https://reviews.llvm.org/D68581



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


[PATCH] D76646: Rename/refactor isIntegerConstantExpression to getIntegerConstantExpression

2020-07-27 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added inline comments.



Comment at: clang/include/clang/AST/Expr.h:513
 
-  /// isIntegerConstantExpr - Return true if this expression is a valid integer
-  /// constant expression, and, if so, return its value in Result.  If not a
-  /// valid i-c-e, return false and fill in Loc (if specified) with the 
location
-  /// of the invalid expression.
+  /// isIntegerConstantExpr - Return the value if this expression is a valid
+  /// integer constant expression.  If not a valid i-c-e, return None and fill

I think the "Return the value..." description now matches 
getIntegerConstantExpr, not isIntegerConstantExpr


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D76646/new/

https://reviews.llvm.org/D76646



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


[PATCH] D85287: Extend -Wtautological-bitwise-compare "bitwise or with non-zero value" warnings

2020-08-05 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added reviewers: jordan_rose, rtrieu.
Herald added a project: clang.
sberg requested review of this revision.

...to C++ constant expression operands.

(I had been puzzled why Clang had not found  "cid#1465512 Wrong operator used"
in the LibreOffice source code, only found by Coverity Scan.  At least building
LibreOffice with this change caused no false positives.)

In C, values of const-qualified variables are never constant expressions, so
nothing should change for C code.

To avoid potential further false positives, restrict this change only to the
"bitwise or with non-zero value" warnings while keeping all other
-Wtautological-bitwise-compare warnings as-is, at least for now.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85287

Files:
  clang/lib/Analysis/CFG.cpp
  clang/test/Sema/warn-bitwise-compare.c
  clang/test/SemaCXX/warn-bitwise-compare.cpp

Index: clang/test/SemaCXX/warn-bitwise-compare.cpp
===
--- clang/test/SemaCXX/warn-bitwise-compare.cpp
+++ clang/test/SemaCXX/warn-bitwise-compare.cpp
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-bitwise-compare %s
 // RUN: %clang_cc1 -fsyntax-only -verify -Wall -Wno-unused %s
 
+int f() { return 3; }
+
+const int const1 = 1;
+constexpr int const2 = 2;
+const int const3 = f();
+
 void test(int x) {
   bool b1 = (8 & x) == 3;
   // expected-warning@-1 {{bitwise comparison always evaluates to false}}
@@ -10,4 +16,15 @@
   // expected-warning@-1 {{bitwise or with non-zero value always evaluates to true}}
   bool b4 = !!(x | 5);
   // expected-warning@-1 {{bitwise or with non-zero value always evaluates to true}}
+  bool b5 = (x | const1);
+  // expected-warning@-1 {{bitwise or with non-zero value always evaluates to true}}
+  bool b6 = (x | const2);
+  // expected-warning@-1 {{bitwise or with non-zero value always evaluates to true}}
+  bool b7 = (x | const3);
+
+  // No warnings at least for now:
+  bool b8 = (x & const1) == 8;
+  bool b9 = (x | const1) == 4;
+  bool b10 = (x & const2) == 8;
+  bool b11 = (x | const2) == 4;
 }
Index: clang/test/Sema/warn-bitwise-compare.c
===
--- clang/test/Sema/warn-bitwise-compare.c
+++ clang/test/Sema/warn-bitwise-compare.c
@@ -8,6 +8,8 @@
   ONE,
 };
 
+const int const1 = 1;
+
 void f(int x) {
   if ((8 & x) == 3) {}  // expected-warning {{bitwise comparison always evaluates to false}}
   if ((x & 8) == 4) {}  // expected-warning {{bitwise comparison always evaluates to false}}
@@ -34,6 +36,9 @@
 
   if ((x & mydefine) == 8) {}
   if ((x | mydefine) == 4) {}
+
+  if ((x & const1) == 8) {}
+  if ((x | const1) == 4) {}
 }
 
 void g(int x) {
@@ -45,4 +50,6 @@
   if (x | ONE) {}  // expected-warning {{bitwise or with non-zero value always evaluates to true}}
 
   if (x | ZERO) {}
+
+  if (x | const1) {}
 }
Index: clang/lib/Analysis/CFG.cpp
===
--- clang/lib/Analysis/CFG.cpp
+++ clang/lib/Analysis/CFG.cpp
@@ -93,15 +93,22 @@
   return isa(E);
 }
 
-/// Helper for tryNormalizeBinaryOperator. Attempts to extract an IntegerLiteral
-/// constant expression or EnumConstantDecl from the given Expr. If it fails,
+/// Helper for tryNormalizeBinaryOperator. Attempts to extract a suitable
+/// integer or enum constant expression from the given Expr. If it fails,
 /// returns nullptr.
-static const Expr *tryTransformToIntOrEnumConstant(const Expr *E) {
+static const Expr *tryTransformToIntOrEnumConstant(const Expr *E,
+   ASTContext &Ctx) {
   E = E->IgnoreParens();
   if (IsIntegerLiteralConstantExpr(E))
 return E;
-  if (auto *DR = dyn_cast(E->IgnoreParenImpCasts()))
-return isa(DR->getDecl()) ? DR : nullptr;
+  if (auto *DR = dyn_cast(E->IgnoreParenImpCasts())) {
+auto *D = DR->getDecl();
+if (isa(D))
+  return DR;
+if (auto *VD = dyn_cast(D))
+  if (VD->isUsableInConstantExpressions(Ctx))
+return DR;
+  }
   return nullptr;
 }
 
@@ -111,11 +118,11 @@
 /// If this fails, at least one of the returned DeclRefExpr or Expr will be
 /// null.
 static std::tuple
-tryNormalizeBinaryOperator(const BinaryOperator *B) {
+tryNormalizeBinaryOperator(const BinaryOperator *B, ASTContext &Ctx) {
   BinaryOperatorKind Op = B->getOpcode();
 
   const Expr *MaybeDecl = B->getLHS();
-  const Expr *Constant = tryTransformToIntOrEnumConstant(B->getRHS());
+  const Expr *Constant = tryTransformToIntOrEnumConstant(B->getRHS(), Ctx);
   // Expr looked like `0 == Foo` instead of `Foo == 0`
   if (Constant == nullptr) {
 // Flip the operator
@@ -129,7 +136,7 @@
   Op = BO_GE;
 
 MaybeDecl = B->getRHS();
-Constant = tryTransformToIntOrEnumConstant(B->getLHS());
+Constant = tryTransformToIntOrEnumConstant(B

[PATCH] D85287: Extend -Wtautological-bitwise-compare "bitwise or with non-zero value" warnings

2020-08-05 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 283204.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85287/new/

https://reviews.llvm.org/D85287

Files:
  clang/lib/Analysis/CFG.cpp
  clang/test/Sema/warn-bitwise-compare.c
  clang/test/SemaCXX/warn-bitwise-compare.cpp

Index: clang/test/SemaCXX/warn-bitwise-compare.cpp
===
--- clang/test/SemaCXX/warn-bitwise-compare.cpp
+++ clang/test/SemaCXX/warn-bitwise-compare.cpp
@@ -1,6 +1,12 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wtautological-bitwise-compare %s
 // RUN: %clang_cc1 -fsyntax-only -verify -Wall -Wno-unused %s
 
+int f() { return 3; }
+
+const int const1 = 1;
+constexpr int const2 = 2;
+const int const3 = f();
+
 void test(int x) {
   bool b1 = (8 & x) == 3;
   // expected-warning@-1 {{bitwise comparison always evaluates to false}}
@@ -10,4 +16,15 @@
   // expected-warning@-1 {{bitwise or with non-zero value always evaluates to true}}
   bool b4 = !!(x | 5);
   // expected-warning@-1 {{bitwise or with non-zero value always evaluates to true}}
+  bool b5 = (x | const1);
+  // expected-warning@-1 {{bitwise or with non-zero value always evaluates to true}}
+  bool b6 = (x | const2);
+  // expected-warning@-1 {{bitwise or with non-zero value always evaluates to true}}
+  bool b7 = (x | const3);
+
+  // No warnings at least for now:
+  bool b8 = (x & const1) == 8;
+  bool b9 = (x | const1) == 4;
+  bool b10 = (x & const2) == 8;
+  bool b11 = (x | const2) == 4;
 }
Index: clang/test/Sema/warn-bitwise-compare.c
===
--- clang/test/Sema/warn-bitwise-compare.c
+++ clang/test/Sema/warn-bitwise-compare.c
@@ -8,6 +8,8 @@
   ONE,
 };
 
+const int const1 = 1;
+
 void f(int x) {
   if ((8 & x) == 3) {}  // expected-warning {{bitwise comparison always evaluates to false}}
   if ((x & 8) == 4) {}  // expected-warning {{bitwise comparison always evaluates to false}}
@@ -34,6 +36,9 @@
 
   if ((x & mydefine) == 8) {}
   if ((x | mydefine) == 4) {}
+
+  if ((x & const1) == 8) {}
+  if ((x | const1) == 4) {}
 }
 
 void g(int x) {
@@ -45,4 +50,6 @@
   if (x | ONE) {}  // expected-warning {{bitwise or with non-zero value always evaluates to true}}
 
   if (x | ZERO) {}
+
+  if (x | const1) {}
 }
Index: clang/lib/Analysis/CFG.cpp
===
--- clang/lib/Analysis/CFG.cpp
+++ clang/lib/Analysis/CFG.cpp
@@ -93,29 +93,36 @@
   return isa(E);
 }
 
-/// Helper for tryNormalizeBinaryOperator. Attempts to extract an IntegerLiteral
-/// constant expression or EnumConstantDecl from the given Expr. If it fails,
+/// Helper for tryNormalizeBinaryOperator. Attempts to extract a suitable
+/// integer or enum constant from the given Expr. If it fails,
 /// returns nullptr.
-static const Expr *tryTransformToIntOrEnumConstant(const Expr *E) {
+static const Expr *tryTransformToIntOrEnumConstant(const Expr *E,
+   ASTContext &Ctx) {
   E = E->IgnoreParens();
   if (IsIntegerLiteralConstantExpr(E))
 return E;
-  if (auto *DR = dyn_cast(E->IgnoreParenImpCasts()))
-return isa(DR->getDecl()) ? DR : nullptr;
+  if (auto *DR = dyn_cast(E->IgnoreParenImpCasts())) {
+auto *D = DR->getDecl();
+if (isa(D))
+  return DR;
+if (auto *VD = dyn_cast(D))
+  if (VD->isUsableInConstantExpressions(Ctx))
+return DR;
+  }
   return nullptr;
 }
 
 /// Tries to interpret a binary operator into `Expr Op NumExpr` form, if
-/// NumExpr is an integer literal or an enum constant.
+/// NumExpr is a suitable integer or an enum constant.
 ///
 /// If this fails, at least one of the returned DeclRefExpr or Expr will be
 /// null.
 static std::tuple
-tryNormalizeBinaryOperator(const BinaryOperator *B) {
+tryNormalizeBinaryOperator(const BinaryOperator *B, ASTContext &Ctx) {
   BinaryOperatorKind Op = B->getOpcode();
 
   const Expr *MaybeDecl = B->getLHS();
-  const Expr *Constant = tryTransformToIntOrEnumConstant(B->getRHS());
+  const Expr *Constant = tryTransformToIntOrEnumConstant(B->getRHS(), Ctx);
   // Expr looked like `0 == Foo` instead of `Foo == 0`
   if (Constant == nullptr) {
 // Flip the operator
@@ -129,7 +136,7 @@
   Op = BO_GE;
 
 MaybeDecl = B->getRHS();
-Constant = tryTransformToIntOrEnumConstant(B->getLHS());
+Constant = tryTransformToIntOrEnumConstant(B->getLHS(), Ctx);
   }
 
   return std::make_tuple(MaybeDecl, Op, Constant);
@@ -140,7 +147,7 @@
 /// literals.
 ///
 /// It's an error to pass this arguments that are not either IntegerLiterals
-/// or DeclRefExprs (that have decls of type EnumConstantDecl)
+/// or DeclRefExprs
 static bool areExprTypesCompatible(const Expr *E1, const Expr *E2) {
   // User intent isn't clear if they're mixing int literals with enum
   // constants.
@@ -151,18 +158,21 @@
   if (!isa(E1))
 return true;
 
-  // IntegerLiterals are handled above and only EnumConstantDecls are expected
+ 

[PATCH] D85287: Extend -Wtautological-bitwise-compare "bitwise or with non-zero value" warnings

2020-08-05 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

My naive assumption was that this warning had initially been restricted to 
integer literals and enumerators to avoid false positives.  Hence my 
conservative approach of extending merely to constant integer expressions for 
now.  Maybe Richard as the original author of the warning (IIUC) can shed some 
light on that original restriction?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85287/new/

https://reviews.llvm.org/D85287

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


[PATCH] D85287: Extend -Wtautological-bitwise-compare "bitwise or with non-zero value" warnings

2020-08-06 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

In D85287#2199463 , @rtrieu wrote:

> Are you planning to allow this change to other warnings that use the same 
> helper functions?

No, I didn't plan to work on this further.  Just scratching that itch of why 
Clang didn't emit that one warning it "obviously" should have emitted.

> Also, have you tried running warning over a codebase?

As I wrote: "At least building LibreOffice with this change caused no false 
positives."  (Or maybe I misunderstand your question.)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85287/new/

https://reviews.llvm.org/D85287

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


[PATCH] D68720: Support -fstack-clash-protection for x86

2020-08-10 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added inline comments.
Herald added a subscriber: dang.



Comment at: clang/include/clang/Driver/Options.td:1778
+  HelpText<"Enable stack clash protection">;
+def fnostack_clash_protection : Flag<["-"], "fnostack-clash-protection">, 
Group,
+  HelpText<"Disable stack clash protection">;

Should this rather spell `"fno-stack-clash-protection"`?  The above change to 
clang/docs/ClangCommandLineReference.rst (but which got overwritten by 

 "[docs] Regenerate ClangCommandLineReference.rst") mentions 
`-fno-stack-clash-protection`, and also GCC calls it like that.  (Though the 
below clang/test/Driver/stack-clash-protection.c does use 
`-fnostack-clash-protection`.)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68720/new/

https://reviews.llvm.org/D68720

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


[PATCH] D85256: Add -Wtautological-value-range-compare warning.

2020-08-11 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

I think this generates a false positive with `test.cc`

  enum E { E1 = 1, E2 = 2 };
  bool f(E e) { return ((e & E1) ? 1 : 0) + ((e & E2) ? 1 : 0) > 1; }

and `clang++ -fsyntax-only -Wtautological-value-range-compare test.cc`

  test.cc:2:62: warning: result of comparison of 1-bit unsigned value > 1 is 
always false [-Wtautological-value-range-compare]
  bool f(E e) { return ((e & E1) ? 1 : 0) + ((e & E2) ? 1 : 0) > 1; }
   ~~~ ^ ~


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85256/new/

https://reviews.llvm.org/D85256

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


[PATCH] D85778: More accurately compute the ranges of possible values for +, -, *, &, %.

2020-08-12 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

Fixes all the false positives it had reported for LibreOffice (which had all 
involved expressions containing either ~ or +).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85778/new/

https://reviews.llvm.org/D85778

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


[PATCH] D68720: Support -fstack-clash-protection for x86

2020-08-12 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

I filed https://bugs.llvm.org/show_bug.cgi?id=47139 "Misspelled 
-fnostack-clash-protection" now.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D68720/new/

https://reviews.llvm.org/D68720

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


[PATCH] D40295: -fsanitize=vptr warnings on bad static types in dynamic_cast and typeid

2017-11-24 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 124154.
sberg added a comment.

Oh, I'd meant to upload the version of the patch where the newly added calls to 
EmitTypeCheck use the default Alignment and SkippedChecks arguments, instead of 
explicitly skipping Alignment and ObjectSize checks.   (That's the version I 
had successfully used in a LibreOffice UBSan 'make check' test build.  But I 
still don't know which version is better.)


https://reviews.llvm.org/D40295

Files:
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/CodeGen/CGExprCXX.cpp
  clang/lib/CodeGen/CodeGenFunction.h
  compiler-rt/lib/ubsan/ubsan_handlers.cc
  compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp

Index: compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp
===
--- compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp
+++ compiler-rt/test/ubsan/TestCases/TypeCheck/vptr.cpp
@@ -1,41 +1,53 @@
-// RUN: %clangxx -frtti -fsanitize=null,vptr -fno-sanitize-recover=null,vptr -g %s -O3 -o %t -mllvm -enable-tail-merge=false
-// RUN: %run %t rT && %run %t mT && %run %t fT && %run %t cT
-// RUN: %run %t rU && %run %t mU && %run %t fU && %run %t cU
-// RUN: %run %t rS && %run %t rV && %run %t oV
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --check-prefix=CHECK-%os-OFFSET --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
-// RUN: %env_ubsan_opts=print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
-// RUN: not %run %t nN 2>&1 | FileCheck %s --check-prefix=CHECK-NULL-MEMFUN --strict-whitespace
+// RUN: %clangxx -frtti -fsanitize=null,vptr -g %s -O3 -o %t -mllvm -enable-tail-merge=false
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t mT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t fT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t cT
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t mU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t fU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t cU
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rS
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t rV
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t oV
+// RUN: %env_ubsan_opts=halt_on_error=1 %run %t zN
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t mS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t fS 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t cS 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t mV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMBER --check-prefix=CHECK-%os-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t fV 2>&1 | FileCheck %s --check-prefix=CHECK-MEMFUN --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t cV 2>&1 | FileCheck %s --check-prefix=CHECK-DOWNCAST --check-prefix=CHECK-%os-DOWNCAST --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t oU 2>&1 | FileCheck %s --check-prefix=CHECK-OFFSET --check-prefix=CHECK-%os-OFFSET --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
+// RUN: %env_ubsan_opts=halt_on_error=1:print_stacktrace=1 not %run %t m0 2>&1 | FileCheck %s --check-prefix=CHECK-INVALID-MEMBER --check-prefix=CHECK-%os-NULL-MEMBER --strict-whitespace
+// RUN: %en

[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2017-12-01 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
Herald added a subscriber: kubamracek.

As discussed in the mail thread 
https://groups.google.com/a/isocpp.org/forum/#!topic/std-discussion/T64_dW3WKUk 
"Calling noexcept function throug non-noexcept pointer is undefined behavior?", 
such a call should not be UB.  However, Clang currently warns about it.

There is no cheap check whether two function type_infos only differ in 
noexcept, so pass those two type_infos as additional data to the 
function_type_mismatch handler (with the optimization of passing a null "static 
callee type" info when that is already noexcept, so the additional check can be 
avoided anyway).  For the Itanium ABI (which appears to only record noexcept 
information for pointer-to-function type_infos, not for function type_infos 
themselves), we then need to check the mangled names for occurrence of "Do" 
representing "noexcept".


https://reviews.llvm.org/D40720

Files:
  clang/lib/CodeGen/CGExpr.cpp
  compiler-rt/lib/ubsan/ubsan_handlers.cc
  compiler-rt/lib/ubsan/ubsan_handlers.h
  compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp

Index: compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
===
--- compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
+++ compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -fsanitize=function %s -O3 -g -o %t
+// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t
 // RUN: %run %t 2>&1 | FileCheck %s
 // Verify that we can disable symbolization if needed:
 // RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
@@ -23,9 +23,47 @@
   reinterpret_cast(reinterpret_cast(f))(42);
 }
 
+void f1(int) {}
+void f2(unsigned int) {}
+void f3(int) noexcept {}
+void f4(unsigned int) noexcept {}
+
+void check_noexcept_calls() {
+  void (*p1)(int);
+  p1 = &f1;
+  p1(0);
+  p1 = reinterpret_cast(&f2);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+  p1(0);
+  p1 = &f3;
+  p1(0);
+  p1 = reinterpret_cast(&f4);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+  p1(0);
+
+  void (*p2)(int) noexcept;
+  p2 = reinterpret_cast(&f1);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f1(int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+  p2 = reinterpret_cast(&f2);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+  p2 = &f3;
+  p2(0);
+  p2 = reinterpret_cast(&f4);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+}
+
 int main(void) {
   make_valid_call();
   make_invalid_call();
+  check_noexcept_calls();
   // Check that no more errors will be printed.
   // CHECK-NOT: runtime error: call to function
   // NOSYM-NOT: runtime error: call to function
Index: compiler-rt/lib/ubsan/ubsan_handlers.h
===
--- compiler-rt/lib/ubsan/ubsan_handlers.h
+++ compiler-rt/lib/ubsan/ubsan_handlers.h
@@ -140,11 +140,12 @@
 struct FunctionTypeMismatchData {
   SourceLocation Loc;
   const TypeDescriptor &Type;
+  ValueHandle NonNoexceptRTTI;
 };
 
 RECOVERABLE(function_type_mismatch,
 FunctionTypeMismatchData *Data,
-ValueHandle Val)
+ValueHandle Val, ValueHandle RTTI)
 
 struct NonNullReturnData {
   SourceLocation AttrLoc;
Index: compiler-rt/lib/ubsan/ubsan_handlers.cc
===
--- compiler-rt/lib/ubsan/ubsan_handlers.cc
+++ compiler-rt/lib/ubsan/ubsan_handlers.cc
@@ -18,6 +18,9 @@
 
 #include "sanitizer_common/sanitizer_common.h"
 
+#include 
+#include 
+
 using namespace __sanitizer;
 using namespace __ubsan;
 
@@ -462,14 +465,50 @@
   Die();
 }
 
-static void handleFunctionTypeMismatch(FunctionTypeMism

[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2017-12-01 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 125152.
sberg added a comment.

(Diff 125121 had accidentally contained a spurious "}". Fixed that now.)


https://reviews.llvm.org/D40720

Files:
  clang/lib/CodeGen/CGExpr.cpp
  compiler-rt/lib/ubsan/ubsan_handlers.cc
  compiler-rt/lib/ubsan/ubsan_handlers.h
  compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp

Index: compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
===
--- compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
+++ compiler-rt/test/ubsan/TestCases/TypeCheck/Function/function.cpp
@@ -1,4 +1,4 @@
-// RUN: %clangxx -fsanitize=function %s -O3 -g -o %t
+// RUN: %clangxx -std=c++17 -fsanitize=function %s -O3 -g -o %t
 // RUN: %run %t 2>&1 | FileCheck %s
 // Verify that we can disable symbolization if needed:
 // RUN: %env_ubsan_opts=symbolize=0 %run %t 2>&1 | FileCheck %s --check-prefix=NOSYM
@@ -23,9 +23,47 @@
   reinterpret_cast(reinterpret_cast(f))(42);
 }
 
+void f1(int) {}
+void f2(unsigned int) {}
+void f3(int) noexcept {}
+void f4(unsigned int) noexcept {}
+
+void check_noexcept_calls() {
+  void (*p1)(int);
+  p1 = &f1;
+  p1(0);
+  p1 = reinterpret_cast(&f2);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+  p1(0);
+  p1 = &f3;
+  p1(0);
+  p1 = reinterpret_cast(&f4);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int)'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int)'
+  p1(0);
+
+  void (*p2)(int) noexcept;
+  p2 = reinterpret_cast(&f1);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f1(int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+  p2 = reinterpret_cast(&f2);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f2(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+  p2 = &f3;
+  p2(0);
+  p2 = reinterpret_cast(&f4);
+  // CHECK: function.cpp:[[@LINE+2]]:3: runtime error: call to function f4(unsigned int) through pointer to incorrect function type 'void (*)(int) noexcept'
+  // NOSYM: function.cpp:[[@LINE+1]]:3: runtime error: call to function (unknown) through pointer to incorrect function type 'void (*)(int) noexcept'
+  p2(0);
+}
+
 int main(void) {
   make_valid_call();
   make_invalid_call();
+  check_noexcept_calls();
   // Check that no more errors will be printed.
   // CHECK-NOT: runtime error: call to function
   // NOSYM-NOT: runtime error: call to function
Index: compiler-rt/lib/ubsan/ubsan_handlers.h
===
--- compiler-rt/lib/ubsan/ubsan_handlers.h
+++ compiler-rt/lib/ubsan/ubsan_handlers.h
@@ -140,11 +140,12 @@
 struct FunctionTypeMismatchData {
   SourceLocation Loc;
   const TypeDescriptor &Type;
+  ValueHandle NonNoexceptRTTI;
 };
 
 RECOVERABLE(function_type_mismatch,
 FunctionTypeMismatchData *Data,
-ValueHandle Val)
+ValueHandle Val, ValueHandle RTTI)
 
 struct NonNullReturnData {
   SourceLocation AttrLoc;
Index: compiler-rt/lib/ubsan/ubsan_handlers.cc
===
--- compiler-rt/lib/ubsan/ubsan_handlers.cc
+++ compiler-rt/lib/ubsan/ubsan_handlers.cc
@@ -18,6 +18,9 @@
 
 #include "sanitizer_common/sanitizer_common.h"
 
+#include 
+#include 
+
 using namespace __sanitizer;
 using namespace __ubsan;
 
@@ -462,14 +465,50 @@
   Die();
 }
 
-static void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data,
-   ValueHandle Function,
+// Check that TI2 represents the same function type as TI1, except that TI2 has
+// "noexcept" and TI1 does not.
+static bool checkForAddedNoexcept(const std::type_info *TI1,
+  const std::type_info *TI2) {
+  const char *Mangled1 = TI1->name();
+  const char *Mangled2 = TI2->name();
+
+  // Skip .
+  if (*Mangled1 == 'V') {
+if (*Mangled2 != 'V')
+  return false;
+++Mangled1;
+++Mangled2;
+  }
+  if (*Mangled1 == 'K') {
+if (*Mangled2 != 'K')
+  return false;
+++Mangled1;
+++Mangled2;
+  }
+
+  // Check for "Do" .
+  if (*Mangled2++ != 'D' || *Mangled2++ != 'o')
+return false;
+
+  // Check remaind

[PATCH] D40167: In stdbool.h, define bool, false, true only in gnu++98

2017-12-08 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rC320135: In stdbool.h, define bool, false, true only in 
gnu++98 (authored by sberg).

Changed prior to commit:
  https://reviews.llvm.org/D40167?vs=123296&id=126095#toc

Repository:
  rC Clang

https://reviews.llvm.org/D40167

Files:
  lib/Headers/stdbool.h
  test/Headers/stdbool.cpp


Index: test/Headers/stdbool.cpp
===
--- test/Headers/stdbool.cpp
+++ test/Headers/stdbool.cpp
@@ -1,13 +1,19 @@
-// RUN: %clang_cc1 -E -dM %s | FileCheck --check-prefix=CHECK-GNU-COMPAT %s
+// RUN: %clang_cc1 -std=gnu++98 -E -dM %s | FileCheck 
--check-prefix=CHECK-GNU-COMPAT-98 %s
+// RUN: %clang_cc1 -std=gnu++11 -E -dM %s | FileCheck 
--check-prefix=CHECK-GNU-COMPAT-11 %s
 // RUN: %clang_cc1 -std=c++98 -E -dM %s | FileCheck 
--check-prefix=CHECK-CONFORMING %s
 // RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -verify -Weverything %s
 #include 
 #define zzz
 
-// CHECK-GNU-COMPAT: #define _Bool bool
-// CHECK-GNU-COMPAT: #define bool bool
-// CHECK-GNU-COMPAT: #define false false
-// CHECK-GNU-COMPAT: #define true true
+// CHECK-GNU-COMPAT-98: #define _Bool bool
+// CHECK-GNU-COMPAT-98: #define bool bool
+// CHECK-GNU-COMPAT-98: #define false false
+// CHECK-GNU-COMPAT-98: #define true true
+
+// CHECK-GNU-COMPAT-11: #define _Bool bool
+// CHECK-GNU-COMPAT-11-NOT: #define bool bool
+// CHECK-GNU-COMPAT-11-NOT: #define false false
+// CHECK-GNU-COMPAT-11-NOT: #define true true
 
 // CHECK-CONFORMING-NOT: #define _Bool
 // CHECK-CONFORMING: #define __CHAR_BIT__
Index: lib/Headers/stdbool.h
===
--- lib/Headers/stdbool.h
+++ lib/Headers/stdbool.h
@@ -32,12 +32,15 @@
 #define true 1
 #define false 0
 #elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
-/* Define _Bool, bool, false, true as a GNU extension. */
+/* Define _Bool as a GNU extension. */
 #define _Bool bool
+#if __cplusplus < 201103L
+/* For C++98, define bool, false, true as a GNU extension. */
 #define bool  bool
 #define false false
 #define true  true
 #endif
+#endif
 
 #define __bool_true_false_are_defined 1
 


Index: test/Headers/stdbool.cpp
===
--- test/Headers/stdbool.cpp
+++ test/Headers/stdbool.cpp
@@ -1,13 +1,19 @@
-// RUN: %clang_cc1 -E -dM %s | FileCheck --check-prefix=CHECK-GNU-COMPAT %s
+// RUN: %clang_cc1 -std=gnu++98 -E -dM %s | FileCheck --check-prefix=CHECK-GNU-COMPAT-98 %s
+// RUN: %clang_cc1 -std=gnu++11 -E -dM %s | FileCheck --check-prefix=CHECK-GNU-COMPAT-11 %s
 // RUN: %clang_cc1 -std=c++98 -E -dM %s | FileCheck --check-prefix=CHECK-CONFORMING %s
 // RUN: %clang_cc1 -fsyntax-only -std=gnu++98 -verify -Weverything %s
 #include 
 #define zzz
 
-// CHECK-GNU-COMPAT: #define _Bool bool
-// CHECK-GNU-COMPAT: #define bool bool
-// CHECK-GNU-COMPAT: #define false false
-// CHECK-GNU-COMPAT: #define true true
+// CHECK-GNU-COMPAT-98: #define _Bool bool
+// CHECK-GNU-COMPAT-98: #define bool bool
+// CHECK-GNU-COMPAT-98: #define false false
+// CHECK-GNU-COMPAT-98: #define true true
+
+// CHECK-GNU-COMPAT-11: #define _Bool bool
+// CHECK-GNU-COMPAT-11-NOT: #define bool bool
+// CHECK-GNU-COMPAT-11-NOT: #define false false
+// CHECK-GNU-COMPAT-11-NOT: #define true true
 
 // CHECK-CONFORMING-NOT: #define _Bool
 // CHECK-CONFORMING: #define __CHAR_BIT__
Index: lib/Headers/stdbool.h
===
--- lib/Headers/stdbool.h
+++ lib/Headers/stdbool.h
@@ -32,12 +32,15 @@
 #define true 1
 #define false 0
 #elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
-/* Define _Bool, bool, false, true as a GNU extension. */
+/* Define _Bool as a GNU extension. */
 #define _Bool bool
+#if __cplusplus < 201103L
+/* For C++98, define bool, false, true as a GNU extension. */
 #define bool  bool
 #define false false
 #define true  true
 #endif
+#endif
 
 #define __bool_true_false_are_defined 1
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D40295: -fsanitize=vptr warnings on bad static types in dynamic_cast and typeid

2017-12-13 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

friendly ping; any input on my two questions maybe?


https://reviews.llvm.org/D40295



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


[PATCH] D40720: No -fsanitize=function warning when calling noexcept function through non-noexcept pointer in C++17

2017-12-13 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

friendly ping


https://reviews.llvm.org/D40720



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


[PATCH] D126864: [clang] Introduce -fstrict-flex-arrays= for stricter handling of flexible arrays

2022-08-29 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

In D126864#3698798 , @sberg wrote:

> I'm surprised that

[...]

> causes a warning?  I would have expected it to be suppressed in this case, as 
> with the lax `-fstrict-flex-arrays=0` default, and only to hit with the 
> stricter `-fstrict-flex-arrays=2`.

appears to be addressed with https://reviews.llvm.org/D132853 "[clang] Fix 
-Warray-bound interaction with -fstrict-flex-arrays=1", thanks


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126864/new/

https://reviews.llvm.org/D126864

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


[PATCH] D126864: [clang] Introduce -fstrict-flex-arrays= for stricter handling of flexible arrays

2022-06-27 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

see https://reviews.llvm.org/D128643 "[clang] -fsanitize=array-bounds: treat 
all trailing size-1 arrays as flexible" for another regression


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126864/new/

https://reviews.llvm.org/D126864

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


[PATCH] D128643: [clang] -fsanitize=array-bounds: treat all trailing size-1 arrays as flexible

2022-06-27 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added a reviewer: serge-sans-paille.
sberg added a project: clang.
Herald added a project: All.
sberg requested review of this revision.

...even if the size resulted from a macro expansion.  This reverts back to the 
behavior prior to
https://github.com/llvm/llvm-project/commit/886715af962de2c92fac4bd37104450345711e4a
 "[clang] Introduce -fstrict-flex-arrays= for stricter handling of flexible 
arrays".  The new behavior caused false out-of-bounds-index reports from e.g. 
HarfBuzz built with `-fsanitize=array-bounds`:  HarfBuzz has various "fake" 
flexible array members of the form

  TypearrayZ[HB_VAR_ARRAY];

in https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-open-type.hh, where 
`HB_VAR_ARRAY` is defined as

  #ifndef HB_VAR_ARRAY
  #define HB_VAR_ARRAY 1
  #endif

in https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-machinery.hh.

Also added a test.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128643

Files:
  clang/include/clang/AST/Expr.h
  clang/lib/AST/Expr.cpp
  clang/lib/CodeGen/CGExpr.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/bounds-checking.c


Index: clang/test/CodeGen/bounds-checking.c
===
--- clang/test/CodeGen/bounds-checking.c
+++ clang/test/CodeGen/bounds-checking.c
@@ -58,3 +58,14 @@
// CHECK-NOT: cont:
return b[i];
 }
+
+#define FLEXIBLE 1
+struct Macro {
+  int a[FLEXIBLE];
+};
+
+// CHECK-LABEL: define {{.*}} @f7
+int f7(struct Macro *m, int i) {
+  // CHECK-NOT: call {{.*}} @llvm.ubsantrap
+  return m->a[i];
+}
Index: clang/lib/Sema/SemaChecking.cpp
===
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -15869,8 +15869,8 @@
   return;
 
 // Also don't warn for flexible array members.
-if (BaseExpr->isFlexibleArrayMember(Context,
-getLangOpts().StrictFlexArrays))
+if (BaseExpr->isFlexibleArrayMember(Context, 
getLangOpts().StrictFlexArrays,
+true))
   return;
 
 // Suppress the warning if the subscript expression (as identified by the
Index: clang/lib/CodeGen/CGExpr.cpp
===
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -932,7 +932,7 @@
   if (const auto *CE = dyn_cast(Base)) {
 if (CE->getCastKind() == CK_ArrayToPointerDecay &&
 !CE->getSubExpr()->IgnoreParens()->isFlexibleArrayMember(
-Context, std::max(StrictFlexArraysLevel, 1))) {
+Context, std::max(StrictFlexArraysLevel, 1), false)) {
   IndexedType = CE->getSubExpr()->getType();
   const ArrayType *AT = IndexedType->castAsArrayTypeUnsafe();
   if (const auto *CAT = dyn_cast(AT))
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -203,8 +203,8 @@
   return false;
 }
 
-bool Expr::isFlexibleArrayMember(ASTContext &Ctx,
- int StrictFlexArraysLevel) const {
+bool Expr::isFlexibleArrayMember(ASTContext &Ctx, int StrictFlexArraysLevel,
+ bool IgnoreSizeFromMacro) const {
   const NamedDecl *ND = nullptr;
   if (const DeclRefExpr *DRE = dyn_cast(this))
 ND = DRE->getDecl();
@@ -260,7 +260,8 @@
 }
 if (ConstantArrayTypeLoc CTL = TL.getAs()) {
   const Expr *SizeExpr = dyn_cast(CTL.getSizeExpr());
-  if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
+  if (!SizeExpr ||
+  (IgnoreSizeFromMacro && SizeExpr->getExprLoc().isMacroID()))
 return false;
 }
 break;
Index: clang/include/clang/AST/Expr.h
===
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -451,7 +451,8 @@
   /// - 1 => [0], [1], [ ]
   /// - 2 => [0], [ ]
   /// - 3 => [ ]
-  bool isFlexibleArrayMember(ASTContext &Ctx, int StrictFlexArraysLevel) const;
+  bool isFlexibleArrayMember(ASTContext &Ctx, int StrictFlexArraysLevel,
+ bool IgnoreSizeFromMacro) const;
 
   /// setValueKind - Set the value kind produced by this expression.
   void setValueKind(ExprValueKind Cat) { ExprBits.ValueKind = Cat; }


Index: clang/test/CodeGen/bounds-checking.c
===
--- clang/test/CodeGen/bounds-checking.c
+++ clang/test/CodeGen/bounds-checking.c
@@ -58,3 +58,14 @@
 	// CHECK-NOT: cont:
 	return b[i];
 }
+
+#define FLEXIBLE 1
+struct Macro {
+  int a[FLEXIBLE];
+};
+
+// CHECK-LABEL: define {{.*}} @f7
+int f7(struct Macro *m, int i) {
+  // CHECK-NOT: call {{.*}} @llvm.ubsantrap
+  return m->a[i];
+}
Index: clang/lib/Sema/SemaChecking.cpp
===
--- c

[PATCH] D126864: [clang] Introduce -fstrict-flex-arrays= for stricter handling of flexible arrays

2022-06-27 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

In D126864#3612149 , @sberg wrote:

> see https://reviews.llvm.org/D128643 "[clang] -fsanitize=array-bounds: treat 
> all trailing size-1 arrays as flexible" for another regression

For the record (now that the original commit has been reverted anyway for now):

Besides the above regression for `-fsanitize=array-bounds` and macro'ized array 
size in HarfBuzz, I also ran into yet another regression when Firebird is built 
with `-fsanitize=array-bounds`:  That project, in 
https://github.com/FirebirdSQL/firebird/blob/master/src/lock/lock_proto.h uses 
a trailing member

srq lhb_hash[1];// Hash table

as a flexible array, but declared in a

  struct lhb : public Firebird::MemoryHeader

that is not a standard-layout class (because the `Firebird::MemoryHeader` base 
class also declares non-static data members).  And `isFlexibleArrayMember` 
returns `false` if the surrounding class is not a standard-layout class.

In the end, what brought back a successful `-fsanitize=array-bounds` 
LibreOffice (which bundles those HarfBuzz and Firebird, among others) for me 
was to exclude the whole set of blocks

  // Don't consider sizes resulting from macro expansions or template argument
  // substitution to form C89 tail-padded arrays.
  
  TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
  while (TInfo) {
TypeLoc TL = TInfo->getTypeLoc();
// Look through typedefs.
if (TypedefTypeLoc TTL = TL.getAs()) {
  const TypedefNameDecl *TDL = TTL.getTypedefNameDecl();
  TInfo = TDL->getTypeSourceInfo();
  continue;
}
if (ConstantArrayTypeLoc CTL = TL.getAs()) {
  const Expr *SizeExpr = dyn_cast(CTL.getSizeExpr());
  if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
return false;
}
break;
  }
  
  const ObjCInterfaceDecl *ID =
  dyn_cast(FD->getDeclContext());
  const RecordDecl *RD = dyn_cast(FD->getDeclContext());
  if (RD) {
if (RD->isUnion())
  return false;
if (const CXXRecordDecl *CRD = dyn_cast(RD)) {
  if (!CRD->isStandardLayout())
return false;
}
  } else if (!ID)
return false;

(by means of an additional `bool` parameter) when `isFlexibleArrayMember` is 
called from `getArrayIndexingBound` (in `clang/lib/CodeGen/CGExpr.cpp`).


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126864/new/

https://reviews.llvm.org/D126864

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


[PATCH] D128643: [clang] -fsanitize=array-bounds: treat all trailing size-1 arrays as flexible

2022-06-27 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg abandoned this revision.
sberg added a comment.

I'm abandoning this as the underlying https://reviews.llvm.org/D126864 "[clang] 
Introduce -fstrict-flex-arrays= for stricter handling of flexible arrays" 
has been reverted for now.

I documented all my issues with that underlying commit (including, but not 
limited to what was presented here) in my comment at 
https://reviews.llvm.org/D126864#3614235.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128643/new/

https://reviews.llvm.org/D128643

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


[PATCH] D128783: Check for more -fsanitize=array-bounds regressions

2022-06-28 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added a reviewer: MaskRay.
sberg added a project: clang.
Herald added a subscriber: StephenFan.
Herald added a project: All.
sberg requested review of this revision.

...that had been introduced with (since reverted) 
https://github.com/llvm/llvm-project/commit/886715af962de2c92fac4bd37104450345711e4a
 "[clang] Introduce -fstrict-flex-arrays= for stricter handling of flexible 
arrays", and caused issues in the wild:

For one, the HarfBuzz project has various "fake" flexible array members of the 
form

  TypearrayZ[HB_VAR_ARRAY];

in https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-open-type.hh, where 
`HB_VAR_ARRAY` is a macro defined as

  #ifndef HB_VAR_ARRAY
  #define HB_VAR_ARRAY 1
  #endif

in https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-machinery.hh.

For another, the Firebird project in 
https://github.com/FirebirdSQL/firebird/blob/master/src/lock/lock_proto.h uses 
a trailing member

  srq lhb_hash[1];// Hash table

as a "fake" flexible array, but declared in a

  struct lhb : public Firebird::MemoryHeader

that is not a standard-layout class (because the `Firebird::MemoryHeader` base 
class also declares non-static data members).

(Checking for the second case required changing the test file from C to C++.)


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D128783

Files:
  clang/test/CodeGen/bounds-checking-fam.c
  clang/test/CodeGen/bounds-checking-fam.cpp


Index: clang/test/CodeGen/bounds-checking-fam.cpp
===
--- clang/test/CodeGen/bounds-checking-fam.cpp
+++ clang/test/CodeGen/bounds-checking-fam.cpp
@@ -14,21 +14,43 @@
 struct Three {
   int a[3];
 };
+#define FLEXIBLE 1
+struct Macro {
+  int a[FLEXIBLE];
+};
+struct Base {
+  int b;
+};
+struct NoStandardLayout : Base {
+  int a[1];
+};
 
-// CHECK-LABEL: define {{.*}} @test_one(
-int test_one(struct One *p, int i) {
+// CHECK-LABEL: define {{.*}} @{{.*}}test_one{{.*}}(
+int test_one(One *p, int i) {
   // CHECK-STRICT-0-NOT: @__ubsan
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_two(
-int test_two(struct Two *p, int i) {
+// CHECK-LABEL: define {{.*}} @{{.*}}test_two{{.*}}(
+int test_two(Two *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_three(
-int test_three(struct Three *p, int i) {
+// CHECK-LABEL: define {{.*}} @{{.*}}test_three{{.*}}(
+int test_three(Three *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_macro{{.*}}(
+int test_macro(Macro *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_nostandardlayout{{.*}}(
+int test_nostandardlayout(NoStandardLayout *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}


Index: clang/test/CodeGen/bounds-checking-fam.cpp
===
--- clang/test/CodeGen/bounds-checking-fam.cpp
+++ clang/test/CodeGen/bounds-checking-fam.cpp
@@ -14,21 +14,43 @@
 struct Three {
   int a[3];
 };
+#define FLEXIBLE 1
+struct Macro {
+  int a[FLEXIBLE];
+};
+struct Base {
+  int b;
+};
+struct NoStandardLayout : Base {
+  int a[1];
+};
 
-// CHECK-LABEL: define {{.*}} @test_one(
-int test_one(struct One *p, int i) {
+// CHECK-LABEL: define {{.*}} @{{.*}}test_one{{.*}}(
+int test_one(One *p, int i) {
   // CHECK-STRICT-0-NOT: @__ubsan
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_two(
-int test_two(struct Two *p, int i) {
+// CHECK-LABEL: define {{.*}} @{{.*}}test_two{{.*}}(
+int test_two(Two *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_three(
-int test_three(struct Three *p, int i) {
+// CHECK-LABEL: define {{.*}} @{{.*}}test_three{{.*}}(
+int test_three(Three *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_macro{{.*}}(
+int test_macro(Macro *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_nostandardlayout{{.*}}(
+int test_nostandardlayout(NoStandardLayout *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D126864: [clang] Introduce -fstrict-flex-arrays= for stricter handling of flexible arrays

2022-06-28 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

In D126864#3614297 , @MaskRay wrote:

> Oh, I did not see this when pushing a test 
> efd90ffbfc427ad4c4675ac1fcae9d53cc7f1322 
>  . 
> Consider adding additional tests in 
> `clang/test/CodeGen/bounds-checking-fam.c`.

see https://reviews.llvm.org/D128783 "Check for more -fsanitize=array-bounds 
regressions"

> It's worth bringing up such issue to the project. GCC and Clang have been 
> working around them so far but they should eventually be fixed.

All the issues I encountered were in C++ code, and I'm not sure replacing one 
non-standard behavior (treating trailing length-one arrays as flexible) with 
another (C flexible array members) is something I feel confident to suggest to 
those projects.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126864/new/

https://reviews.llvm.org/D126864

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


[PATCH] D128783: [test] Check for more -fsanitize=array-bounds regressions

2022-06-30 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 441313.
sberg added a comment.

Updated the prospective git commit message as follow:

  [test] Check for more -fsanitize=array-bounds behavior
  
  ...that had temporarily regressed with (since reverted)
  

  "[clang] Introduce -fstrict-flex-arrays= for stricter handling of flexible
  arrays", and had then been seen to cause issues in the wild:
  
  For one, the HarfBuzz project has various "fake" flexible array members of the
  form
  
  > TypearrayZ[HB_VAR_ARRAY];
  
  in , where
  HB_VAR_ARRAY is a macro defined as
  
  > #ifndef HB_VAR_ARRAY
  > #define HB_VAR_ARRAY 1
  > #endif
  
  in .
  
  For another, the Firebird project in
   
uses
  a trailing member
  
  > srq lhb_hash[1];// Hash table
  
  as a "fake" flexible array, but declared in a
  
  > struct lhb : public Firebird::MemoryHeader
  
  that is not a standard-layout class (because the Firebird::MemoryHeader base
  class also declares non-static data members).
  
  (The second case is specific to C++.  Extend the test setup so that all the
  other tests are now run for both C and C++, just in case the behavior could 
ever
  start to diverge for those two languages.)
  
  Differential Revision: https://reviews.llvm.org/D128783


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128783/new/

https://reviews.llvm.org/D128783

Files:
  clang/test/CodeGen/bounds-checking-fam.c


Index: clang/test/CodeGen/bounds-checking-fam.c
===
--- clang/test/CodeGen/bounds-checking-fam.c
+++ clang/test/CodeGen/bounds-checking-fam.c
@@ -1,5 +1,6 @@
 // REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds -x c++ %s 
-o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0,CXX,CXX-STRICT-0
 
 /// Before flexible array member was added to C99, many projects use a
 /// one-element array as the last emember of a structure as an alternative.
@@ -14,21 +15,48 @@
 struct Three {
   int a[3];
 };
+#define FLEXIBLE 1
+struct Macro {
+  int a[FLEXIBLE];
+};
 
-// CHECK-LABEL: define {{.*}} @test_one(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_one{{.*}}(
 int test_one(struct One *p, int i) {
   // CHECK-STRICT-0-NOT: @__ubsan
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_two(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_two{{.*}}(
 int test_two(struct Two *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_three(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_three{{.*}}(
 int test_three(struct Three *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_macro{{.*}}(
+int test_macro(struct Macro *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+#if defined __cplusplus
+
+struct Base {
+  int b;
+};
+struct NoStandardLayout : Base {
+  int a[1];
+};
+
+// CXX-LABEL: define {{.*}} @{{.*}}test_nostandardlayout{{.*}}(
+int test_nostandardlayout(NoStandardLayout *p, int i) {
+  // CXX-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+#endif


Index: clang/test/CodeGen/bounds-checking-fam.c
===
--- clang/test/CodeGen/bounds-checking-fam.c
+++ clang/test/CodeGen/bounds-checking-fam.c
@@ -1,5 +1,6 @@
 // REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds -x c++ %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0,CXX,CXX-STRICT-0
 
 /// Before flexible array member was added to C99, many projects use a
 /// one-element array as the last emember of a structure as an alternative.
@@ -14,21 +15,48 @@
 struct Three {
   int a[3];
 };
+#define FLEXIBLE 1
+struct Macro {
+  int a[FLEXIBLE];
+};
 
-// CHECK-LABEL: define {{.*}} @test_one(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_one{{.*}}(
 int test_one(struct One *p, int i) {
   // CHECK-STRICT-0-NOT: @__ubsan
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_two(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_two{{.*}}(
 int test_two(struct Two *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
 
-//

[PATCH] D128783: [test] Check for more -fsanitize=array-bounds regressions

2022-07-01 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 441640.
sberg added a comment.

added test involving template argument substitution


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128783/new/

https://reviews.llvm.org/D128783

Files:
  clang/test/CodeGen/bounds-checking-fam.c


Index: clang/test/CodeGen/bounds-checking-fam.c
===
--- clang/test/CodeGen/bounds-checking-fam.c
+++ clang/test/CodeGen/bounds-checking-fam.c
@@ -1,5 +1,6 @@
 // REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds -x c++ %s 
-o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0,CXX,CXX-STRICT-0
 
 /// Before flexible array member was added to C99, many projects use a
 /// one-element array as the last emember of a structure as an alternative.
@@ -15,20 +16,58 @@
   int a[3];
 };
 
-// CHECK-LABEL: define {{.*}} @test_one(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_one{{.*}}(
 int test_one(struct One *p, int i) {
   // CHECK-STRICT-0-NOT: @__ubsan
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_two(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_two{{.*}}(
 int test_two(struct Two *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_three(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_three{{.*}}(
 int test_three(struct Three *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
+
+#define FLEXIBLE 1
+struct Macro {
+  int a[FLEXIBLE];
+};
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_macro{{.*}}(
+int test_macro(struct Macro *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+#if defined __cplusplus
+
+struct Base {
+  int b;
+};
+struct NoStandardLayout : Base {
+  int a[1];
+};
+
+// CXX-LABEL: define {{.*}} @{{.*}}test_nostandardlayout{{.*}}(
+int test_nostandardlayout(NoStandardLayout *p, int i) {
+  // CXX-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+template struct Template {
+  int a[N];
+};
+
+// CXX-LABEL: define {{.*}} @{{.*}}test_template{{.*}}(
+int test_template(Template<1> *p, int i) {
+  // CXX-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+#endif


Index: clang/test/CodeGen/bounds-checking-fam.c
===
--- clang/test/CodeGen/bounds-checking-fam.c
+++ clang/test/CodeGen/bounds-checking-fam.c
@@ -1,5 +1,6 @@
 // REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds -x c++ %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0,CXX,CXX-STRICT-0
 
 /// Before flexible array member was added to C99, many projects use a
 /// one-element array as the last emember of a structure as an alternative.
@@ -15,20 +16,58 @@
   int a[3];
 };
 
-// CHECK-LABEL: define {{.*}} @test_one(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_one{{.*}}(
 int test_one(struct One *p, int i) {
   // CHECK-STRICT-0-NOT: @__ubsan
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_two(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_two{{.*}}(
 int test_two(struct Two *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_three(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_three{{.*}}(
 int test_three(struct Three *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
+
+#define FLEXIBLE 1
+struct Macro {
+  int a[FLEXIBLE];
+};
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_macro{{.*}}(
+int test_macro(struct Macro *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+#if defined __cplusplus
+
+struct Base {
+  int b;
+};
+struct NoStandardLayout : Base {
+  int a[1];
+};
+
+// CXX-LABEL: define {{.*}} @{{.*}}test_nostandardlayout{{.*}}(
+int test_nostandardlayout(NoStandardLayout *p, int i) {
+  // CXX-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+template struct Template {
+  int a[N];
+};
+
+// CXX-LABEL: define {{.*}} @{{.*}}test_template{{.*}}(
+int test_template(Template<1> *p, int i) {
+  // CXX-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+#endif
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D128783: [test] Check for more -fsanitize=array-bounds regressions

2022-07-01 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg marked an inline comment as done.
sberg added inline comments.



Comment at: clang/test/CodeGen/bounds-checking-fam.c:59
+  // CXX-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}

serge-sans-paille wrote:
> Another C++-specific behavior: if the bound results from the substitution of 
> a template parameter, event if its value is 1 it's currently not considered a 
> FAM
I hadn't encountered that in the wild, so didn't bother to create a test for 
it; but yes, makes sense to add it too


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128783/new/

https://reviews.llvm.org/D128783

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


[PATCH] D128783: [test] Check for more -fsanitize=array-bounds regressions

2022-07-04 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
sberg marked an inline comment as done.
Closed by commit rG4996e3f68315: [test] Check for more -fsanitize=array-bounds 
behavior (authored by sberg).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D128783/new/

https://reviews.llvm.org/D128783

Files:
  clang/test/CodeGen/bounds-checking-fam.c


Index: clang/test/CodeGen/bounds-checking-fam.c
===
--- clang/test/CodeGen/bounds-checking-fam.c
+++ clang/test/CodeGen/bounds-checking-fam.c
@@ -1,5 +1,6 @@
 // REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds %s -o - | 
FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds -x c++ %s 
-o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0,CXX,CXX-STRICT-0
 
 /// Before flexible array member was added to C99, many projects use a
 /// one-element array as the last emember of a structure as an alternative.
@@ -15,20 +16,58 @@
   int a[3];
 };
 
-// CHECK-LABEL: define {{.*}} @test_one(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_one{{.*}}(
 int test_one(struct One *p, int i) {
   // CHECK-STRICT-0-NOT: @__ubsan
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_two(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_two{{.*}}(
 int test_two(struct Two *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_three(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_three{{.*}}(
 int test_three(struct Three *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
+
+#define FLEXIBLE 1
+struct Macro {
+  int a[FLEXIBLE];
+};
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_macro{{.*}}(
+int test_macro(struct Macro *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+#if defined __cplusplus
+
+struct Base {
+  int b;
+};
+struct NoStandardLayout : Base {
+  int a[1];
+};
+
+// CXX-LABEL: define {{.*}} @{{.*}}test_nostandardlayout{{.*}}(
+int test_nostandardlayout(NoStandardLayout *p, int i) {
+  // CXX-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+template struct Template {
+  int a[N];
+};
+
+// CXX-LABEL: define {{.*}} @{{.*}}test_template{{.*}}(
+int test_template(Template<1> *p, int i) {
+  // CXX-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+#endif


Index: clang/test/CodeGen/bounds-checking-fam.c
===
--- clang/test/CodeGen/bounds-checking-fam.c
+++ clang/test/CodeGen/bounds-checking-fam.c
@@ -1,5 +1,6 @@
 // REQUIRES: x86-registered-target
 // RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0
+// RUN: %clang_cc1 -emit-llvm -triple x86_64 -fsanitize=array-bounds -x c++ %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-STRICT-0,CXX,CXX-STRICT-0
 
 /// Before flexible array member was added to C99, many projects use a
 /// one-element array as the last emember of a structure as an alternative.
@@ -15,20 +16,58 @@
   int a[3];
 };
 
-// CHECK-LABEL: define {{.*}} @test_one(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_one{{.*}}(
 int test_one(struct One *p, int i) {
   // CHECK-STRICT-0-NOT: @__ubsan
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_two(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_two{{.*}}(
 int test_two(struct Two *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
 
-// CHECK-LABEL: define {{.*}} @test_three(
+// CHECK-LABEL: define {{.*}} @{{.*}}test_three{{.*}}(
 int test_three(struct Three *p, int i) {
   // CHECK-STRICT-0: call void @__ubsan_handle_out_of_bounds_abort(
   return p->a[i] + (p->a)[i];
 }
+
+#define FLEXIBLE 1
+struct Macro {
+  int a[FLEXIBLE];
+};
+
+// CHECK-LABEL: define {{.*}} @{{.*}}test_macro{{.*}}(
+int test_macro(struct Macro *p, int i) {
+  // CHECK-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+#if defined __cplusplus
+
+struct Base {
+  int b;
+};
+struct NoStandardLayout : Base {
+  int a[1];
+};
+
+// CXX-LABEL: define {{.*}} @{{.*}}test_nostandardlayout{{.*}}(
+int test_nostandardlayout(NoStandardLayout *p, int i) {
+  // CXX-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+template struct Template {
+  int a[N];
+};
+
+// CXX-LABEL: define {{.*}} @{{.*}}test_template{{.*}}(
+int test_template(Template<1> *p, int i) {
+  // CXX-STRICT-0-NOT: @__ubsan
+  return p->a[i] + (p->a)[i];
+}
+
+#endif
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listi

[PATCH] D126864: [clang] Introduce -fstrict-flex-arrays= for stricter handling of flexible arrays

2022-08-04 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

I'm surprised that

  $ cat test.c
  struct S {
  int m1;
  int m2[1];
  };
  void f(struct S * s) {
  s->m2[1] = 0;
  }
  
  $ clang -fsyntax-only -fstrict-flex-arrays=1 test.c
  test.c:6:5: warning: array index 1 is past the end of the array (which 
contains 1 element) [-Warray-bounds]
  s->m2[1] = 0;
  ^ ~
  test.c:3:5: note: array 'm2' declared here
  int m2[1];
  ^
  1 warning generated.

causes a warning?  I would have expected it to be suppressed in this case, as 
with the lax `-fstrict-flex-arrays=0` default, and only to hit with the 
stricter `-fstrict-flex-arrays=2`.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126864/new/

https://reviews.llvm.org/D126864

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


[PATCH] D131307: [Clang] Allow downgrading to a warning the diagnostic for setting a non fixed enum to a value outside the range of the enumeration values

2022-08-10 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

With this commit,

  $ cat test.cc
  #include "boost/numeric/conversion/cast.hpp"
  int main() { return boost::numeric_cast(0L); }
  
  $ clang++ test.cc

succeeds without any diagnostic, while with its parent commit 
https://github.com/llvm/llvm-project/commit/b3645353041818f61e2580635409ddb81ff5a272
 " [Clang] Diagnose ill-formed constant expression when setting a non fixed 
enum to a value outside the range of the enumeration values" it had started to 
fail with

  In file included from test.cc:1:
  In file included from /usr/include/boost/numeric/conversion/cast.hpp:33:
  In file included from /usr/include/boost/numeric/conversion/converter.hpp:13:
  In file included from 
/usr/include/boost/numeric/conversion/conversion_traits.hpp:13:
  In file included from 
/usr/include/boost/numeric/conversion/detail/conversion_traits.hpp:18:
  In file included from 
/usr/include/boost/numeric/conversion/detail/int_float_mixture.hpp:19:
  In file included from /usr/include/boost/mpl/integral_c.hpp:32:
  /usr/include/boost/mpl/aux_/integral_wrapper.hpp:73:31: error: non-type 
template argument is not a constant expression
  typedef AUX_WRAPPER_INST( 
BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value - 1)) ) prior;
  
~~^~~~
  /usr/include/boost/mpl/aux_/static_cast.hpp:24:47: note: expanded from macro 
'BOOST_MPL_AUX_STATIC_CAST'
  #   define BOOST_MPL_AUX_STATIC_CAST(T, expr) static_cast(expr)
^
  /usr/include/boost/mpl/integral_c.hpp:31:54: note: expanded from macro 
'AUX_WRAPPER_INST'
  #define AUX_WRAPPER_INST(value) AUX_WRAPPER_NAME< T, value >
   ^
  /usr/include/boost/numeric/conversion/detail/meta.hpp:30:46: note: in 
instantiation of template class 
'mpl_::integral_c' requested here
 enum { x = ( BOOST_MPL_AUX_VALUE_WKND(T1)::value == 
BOOST_MPL_AUX_VALUE_WKND(T2)::value ) };
   ^
  /usr/include/boost/mpl/if.hpp:63:68: note: in instantiation of template class 
'boost::numeric::convdetail::equal_to, 
mpl_::integral_c>' requested here
BOOST_MPL_AUX_STATIC_CAST(bool, BOOST_MPL_AUX_VALUE_WKND(T1)::value)
 ^
  /usr/include/boost/mpl/eval_if.hpp:37:22: note: in instantiation of template 
class 
'boost::mpl::if_, 
mpl_::integral_c>, 
boost::mpl::identity>, 
boost::mpl::eval_if, 
mpl_::integral_c>, 
boost::mpl::identity>>, 
boost::mpl::if_, 
mpl_::integral_c>, 
boost::mpl::identity>, boost::mpl::identity' requested here
  typedef typename if_::type f_;
   ^
  /usr/include/boost/numeric/conversion/detail/meta.hpp:81:12: note: in 
instantiation of template class 
'boost::mpl::eval_if, 
mpl_::integral_c>, 
boost::mpl::identity>, 
boost::mpl::eval_if, 
mpl_::integral_c>, 
boost::mpl::identity>>, 
boost::mpl::if_, 
mpl_::integral_c>, 
boost::mpl::identity>, boost::mpl::identity' requested here
mpl::eval_if::type
 ^
  /usr/include/boost/numeric/conversion/detail/udt_builtin_mixture.hpp:41:7: 
note: in instantiation of template class 
'boost::numeric::convdetail::ct_switch4, 
mpl_::integral_c, 
mpl_::integral_c, 
mpl_::integral_c, 
boost::numeric::convdetail::get_subranged_BuiltIn2BuiltIn, 
boost::mpl::identity>, 
boost::mpl::identity>, boost::mpl::identity>>' requested here
ct_switch4::type
  ^
  /usr/include/boost/numeric/conversion/conversion_traits.hpp:22:7: note: in 
instantiation of template class 
'boost::numeric::convdetail::non_trivial_traits_impl' requested here
  : convdetail::get_conversion_traits::type
^
  /usr/include/boost/numeric/conversion/detail/converter.hpp:584:22: note: in 
instantiation of template class 'boost::numeric::conversion_traits' 
requested here
  typedef typename Traits::trivial trivial ;
   ^
  /usr/include/boost/numeric/conversion/converter.hpp:29:32: note: in 
instantiation of template class 
'boost::numeric::convdetail::get_converter_impl, boost::numeric::def_overflow_handler, boost::numeric::Trunc, 
boost::numeric::raw_converter>, 
boost::numeric::UseInternalRangeChecker>' requested here
  struct converter : convdetail::get_converter_impl, 
boost::numeric::def_overflow_handler, boost::numeric::Trunc>' requested 
here
  return converter::convert(arg);
 ^
  test.cc:2:28: note: in instantiation of function template specialization 
'boost::numeric_cast' requested here
  int main() { return boost::numeric_cast(0L); }
 ^
  /usr/include/boost/mpl/aux_/integral_wrapper.hpp:73:31: note: integer value 
-1 is outside the valid range of values [0, 3] for this enumeration type
  typedef AUX_WRAPPER_INST( 
BOOST_MPL_AUX_STATIC_CAST(AUX_WRAPPER_VALUE_TYPE, (value - 1)) ) prior;

[PATCH] D119721: [clang][lex] Use `ConstSearchDirIterator` in lookup cache

2022-03-22 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added subscribers: rnk, sberg.
sberg added a comment.
Herald added a project: All.

I started to experience Clang crashing when building Firebird (as part of 
building LibreOffice) in clang-cl mode on Windows, and I think it is due to 
this change in combination with D2733  by @rnk:

When `HeaderSearch::LookupFile` exits through one of the `if 
(checkMSVCHeaderSearch...` branches introduced in D2733 
, it does not update `CacheLookup.HitIt` 
(through one of the calls to `cacheLookupSuccess` or via the "Otherwise, didn't 
find it" step at the end of the function), even though it already may have done 
the "We will fill in our found location below, so prime the start point value" 
step of calling `CacheLookup.reset`.  That means that a later call to 
`HeaderSearch::LookupFile` can go into the `if (!SkipCache && 
CacheLookup.StartIt == NextIt)` true branch, set `It = CacheLookup.HitIt` to an 
invalid iterator (the default `HitIt = nullptr` value), and then assert/crash 
when dereferencing that invalid `It`.

Which was not an issue before this change, as the initial `HitIdx = 0` was not 
an invalid value, so `i = CacheLookup.HitIdx` never caused `i` to become 
invalid.

I locally worked around this in my build with

  -  if (!SkipCache && CacheLookup.StartIt == NextIt) {
  +  if (!SkipCache && CacheLookup.StartIt == NextIt && CacheLookup.HitIt) {

which seems to work well, but I'm not sure what the best real fix would be.  
(D2733  stated "I believe the correct behavior 
here is to avoid updating the cache when we find the header via MSVC's search 
rules.")


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D119721/new/

https://reviews.llvm.org/D119721

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


[PATCH] D35562: Support GNU extension StmtExpr in constexpr function

2017-08-18 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 111632.
sberg added a comment.

(the original diff had inadvertently lacked full -U99 context; uploaded a 
new diff)


https://reviews.llvm.org/D35562

Files:
  clang/lib/AST/ExprConstant.cpp
  clang/test/SemaCXX/constant-expression-cxx1y.cpp


Index: clang/test/SemaCXX/constant-expression-cxx1y.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx1y.cpp
+++ clang/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -781,9 +781,8 @@
 return ({ int n; n; }); // expected-note {{object of type 'int' is not 
initialized}}
   }
 
-  // FIXME: We should handle the void statement expression case.
-  constexpr int h() { // expected-error {{never produces a constant}}
-({ if (true) {} }); // expected-note {{not supported}}
+  constexpr int h() {
+({ if (true) {} });
 return 0;
   }
 }
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -4837,16 +4837,10 @@
 
 for (CompoundStmt::const_body_iterator BI = CS->body_begin(),
BE = CS->body_end();
- /**/; ++BI) {
-  if (BI + 1 == BE) {
-const Expr *FinalExpr = dyn_cast(*BI);
-if (!FinalExpr) {
-  Info.FFDiag((*BI)->getLocStart(),
-diag::note_constexpr_stmt_expr_unsupported);
-  return false;
-}
-return this->Visit(FinalExpr);
-  }
+ BI != BE; ++BI) {
+  if (BI + 1 == BE)
+if (const Expr *FinalExpr = dyn_cast(*BI))
+  return this->Visit(FinalExpr);
 
   APValue ReturnValue;
   StmtResult Result = { ReturnValue, nullptr };
@@ -4862,7 +4856,7 @@
   }
 }
 
-llvm_unreachable("Return from function from the loop above.");
+return true;
   }
 
   /// Visit a value which is evaluated, but whose value is ignored.


Index: clang/test/SemaCXX/constant-expression-cxx1y.cpp
===
--- clang/test/SemaCXX/constant-expression-cxx1y.cpp
+++ clang/test/SemaCXX/constant-expression-cxx1y.cpp
@@ -781,9 +781,8 @@
 return ({ int n; n; }); // expected-note {{object of type 'int' is not initialized}}
   }
 
-  // FIXME: We should handle the void statement expression case.
-  constexpr int h() { // expected-error {{never produces a constant}}
-({ if (true) {} }); // expected-note {{not supported}}
+  constexpr int h() {
+({ if (true) {} });
 return 0;
   }
 }
Index: clang/lib/AST/ExprConstant.cpp
===
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -4837,16 +4837,10 @@
 
 for (CompoundStmt::const_body_iterator BI = CS->body_begin(),
BE = CS->body_end();
- /**/; ++BI) {
-  if (BI + 1 == BE) {
-const Expr *FinalExpr = dyn_cast(*BI);
-if (!FinalExpr) {
-  Info.FFDiag((*BI)->getLocStart(),
-diag::note_constexpr_stmt_expr_unsupported);
-  return false;
-}
-return this->Visit(FinalExpr);
-  }
+ BI != BE; ++BI) {
+  if (BI + 1 == BE)
+if (const Expr *FinalExpr = dyn_cast(*BI))
+  return this->Visit(FinalExpr);
 
   APValue ReturnValue;
   StmtResult Result = { ReturnValue, nullptr };
@@ -4862,7 +4856,7 @@
   }
 }
 
-llvm_unreachable("Return from function from the loop above.");
+return true;
   }
 
   /// Visit a value which is evaluated, but whose value is ignored.
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D35564: Suppress -pedantic warnings about GNU extension StmtExpr in glibc's assert macro

2017-08-18 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 111634.
sberg added a comment.

(the original diff had inadvertently lacked full -U99 context; uploaded a 
new diff)


https://reviews.llvm.org/D35564

Files:
  clang/lib/Basic/DiagnosticIDs.cpp
  clang/test/SemaCXX/warn-sysheader-macro.cpp


Index: clang/test/SemaCXX/warn-sysheader-macro.cpp
===
--- clang/test/SemaCXX/warn-sysheader-macro.cpp
+++ clang/test/SemaCXX/warn-sysheader-macro.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow -Wold-style-cast %s
+// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow -Wold-style-cast -pedantic %s
 
 // Test that macro expansions from system headers don't trigger 'syntactic'
 // warnings that are not actionable.
@@ -12,6 +12,8 @@
 
 #define OLD_STYLE_CAST(a) ((int) (a))
 
+#define ASSERT(a) ({ if (a) {} else {} })
+
 #else
 
 #define IS_SYSHEADER
@@ -32,4 +34,9 @@
   int i = OLD_STYLE_CAST(0);
 }
 
+void testExtension() {
+  ASSERT(true);
+  ASSERT(({ true; })); // expected-warning {{use of GNU statement expression 
extension}}
+}
+
 #endif
Index: clang/lib/Basic/DiagnosticIDs.cpp
===
--- clang/lib/Basic/DiagnosticIDs.cpp
+++ clang/lib/Basic/DiagnosticIDs.cpp
@@ -396,6 +396,14 @@
   return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag));
 }
 
+static bool isSystemFunctionMacroBodyExpansion(SourceLocation Loc,
+   const SourceManager &SM) {
+  if (!(SM.isInSystemMacro(Loc) && SM.isMacroBodyExpansion(Loc)))
+return false;
+  auto Range = SM.getImmediateExpansionRange(Loc);
+  return Range.first != Range.second;
+}
+
 /// \brief Based on the way the client configured the Diagnostic
 /// object, classify the specified diagnostic ID into a Level, consumable by
 /// the DiagnosticClient.
@@ -469,8 +477,10 @@
   // because we also want to ignore extensions and warnings in -Werror and
   // -pedantic-errors modes, which *map* warnings/extensions to errors.
   if (State->SuppressSystemWarnings && !ShowInSystemHeader && Loc.isValid() &&
-  Diag.getSourceManager().isInSystemHeader(
-  Diag.getSourceManager().getExpansionLoc(Loc)))
+  (Diag.getSourceManager().isInSystemHeader(
+  Diag.getSourceManager().getExpansionLoc(Loc)) ||
+   (IsExtensionDiag &&
+isSystemFunctionMacroBodyExpansion(Loc, Diag.getSourceManager()
 return diag::Severity::Ignored;
 
   return Result;


Index: clang/test/SemaCXX/warn-sysheader-macro.cpp
===
--- clang/test/SemaCXX/warn-sysheader-macro.cpp
+++ clang/test/SemaCXX/warn-sysheader-macro.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow -Wold-style-cast %s
+// RUN: %clang_cc1 -verify -fsyntax-only -Wshadow -Wold-style-cast -pedantic %s
 
 // Test that macro expansions from system headers don't trigger 'syntactic'
 // warnings that are not actionable.
@@ -12,6 +12,8 @@
 
 #define OLD_STYLE_CAST(a) ((int) (a))
 
+#define ASSERT(a) ({ if (a) {} else {} })
+
 #else
 
 #define IS_SYSHEADER
@@ -32,4 +34,9 @@
   int i = OLD_STYLE_CAST(0);
 }
 
+void testExtension() {
+  ASSERT(true);
+  ASSERT(({ true; })); // expected-warning {{use of GNU statement expression extension}}
+}
+
 #endif
Index: clang/lib/Basic/DiagnosticIDs.cpp
===
--- clang/lib/Basic/DiagnosticIDs.cpp
+++ clang/lib/Basic/DiagnosticIDs.cpp
@@ -396,6 +396,14 @@
   return toLevel(getDiagnosticSeverity(DiagID, Loc, Diag));
 }
 
+static bool isSystemFunctionMacroBodyExpansion(SourceLocation Loc,
+   const SourceManager &SM) {
+  if (!(SM.isInSystemMacro(Loc) && SM.isMacroBodyExpansion(Loc)))
+return false;
+  auto Range = SM.getImmediateExpansionRange(Loc);
+  return Range.first != Range.second;
+}
+
 /// \brief Based on the way the client configured the Diagnostic
 /// object, classify the specified diagnostic ID into a Level, consumable by
 /// the DiagnosticClient.
@@ -469,8 +477,10 @@
   // because we also want to ignore extensions and warnings in -Werror and
   // -pedantic-errors modes, which *map* warnings/extensions to errors.
   if (State->SuppressSystemWarnings && !ShowInSystemHeader && Loc.isValid() &&
-  Diag.getSourceManager().isInSystemHeader(
-  Diag.getSourceManager().getExpansionLoc(Loc)))
+  (Diag.getSourceManager().isInSystemHeader(
+  Diag.getSourceManager().getExpansionLoc(Loc)) ||
+   (IsExtensionDiag &&
+isSystemFunctionMacroBodyExpansion(Loc, Diag.getSourceManager()
 return diag::Severity::Ignored;
 
   return Result;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87030: Adapt CastExpr::getSubExprAsWritten to ConstantExpr

2020-09-18 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 292728.
sberg added a comment.

ping

(addressed the clang-tidy nitpick)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87030/new/

https://reviews.llvm.org/D87030

Files:
  clang/lib/AST/Expr.cpp
  clang/unittests/Tooling/CastExprTest.cpp


Index: clang/unittests/Tooling/CastExprTest.cpp
===
--- clang/unittests/Tooling/CastExprTest.cpp
+++ clang/unittests/Tooling/CastExprTest.cpp
@@ -34,4 +34,24 @@
 "S1 f(S2 s) { return static_cast(s); }\n");
 }
 
+// Verify that getSubExprAsWritten looks through a ConstantExpr in a scenario
+// like
+//
+//   CXXFunctionalCastExpr functional cast to struct S 
+//   `-ConstantExpr 'S'
+// |-value: Struct
+// `-CXXConstructExpr 'S' 'void (int)'
+//   `-IntegerLiteral 'int' 0
+TEST(CastExprTest, GetSubExprAsWrittenThroughConstantExpr) {
+CastExprVisitor Visitor;
+Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) {
+  auto *Sub = Expr->getSubExprAsWritten();
+  EXPECT_TRUE(isa(Sub))
+<< "Expected IntegerLiteral, but saw " << Sub->getStmtClassName();
+};
+Visitor.runOver("struct S { consteval S(int) {} };\n"
+"S f() { return S(0); }\n",
+CastExprVisitor::Lang_CXX2a);
+}
+
 }
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1825,7 +1825,7 @@
 // subexpression describing the call; strip it off.
 if (E->getCastKind() == CK_ConstructorConversion)
   SubExpr =
-skipImplicitTemporary(cast(SubExpr)->getArg(0));
+
skipImplicitTemporary(cast(SubExpr->IgnoreImplicit())->getArg(0));
 else if (E->getCastKind() == CK_UserDefinedConversion) {
   assert((isa(SubExpr) ||
   isa(SubExpr)) &&


Index: clang/unittests/Tooling/CastExprTest.cpp
===
--- clang/unittests/Tooling/CastExprTest.cpp
+++ clang/unittests/Tooling/CastExprTest.cpp
@@ -34,4 +34,24 @@
 "S1 f(S2 s) { return static_cast(s); }\n");
 }
 
+// Verify that getSubExprAsWritten looks through a ConstantExpr in a scenario
+// like
+//
+//   CXXFunctionalCastExpr functional cast to struct S 
+//   `-ConstantExpr 'S'
+// |-value: Struct
+// `-CXXConstructExpr 'S' 'void (int)'
+//   `-IntegerLiteral 'int' 0
+TEST(CastExprTest, GetSubExprAsWrittenThroughConstantExpr) {
+CastExprVisitor Visitor;
+Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) {
+  auto *Sub = Expr->getSubExprAsWritten();
+  EXPECT_TRUE(isa(Sub))
+<< "Expected IntegerLiteral, but saw " << Sub->getStmtClassName();
+};
+Visitor.runOver("struct S { consteval S(int) {} };\n"
+"S f() { return S(0); }\n",
+CastExprVisitor::Lang_CXX2a);
+}
+
 }
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1825,7 +1825,7 @@
 // subexpression describing the call; strip it off.
 if (E->getCastKind() == CK_ConstructorConversion)
   SubExpr =
-skipImplicitTemporary(cast(SubExpr)->getArg(0));
+skipImplicitTemporary(cast(SubExpr->IgnoreImplicit())->getArg(0));
 else if (E->getCastKind() == CK_UserDefinedConversion) {
   assert((isa(SubExpr) ||
   isa(SubExpr)) &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87030: Adapt CastExpr::getSubExprAsWritten to ConstantExpr

2020-09-25 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

ping^2


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87030/new/

https://reviews.llvm.org/D87030

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


[PATCH] D87030: Adapt CastExpr::getSubExprAsWritten to ConstantExpr

2020-09-02 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added a reviewer: rsmith.
Herald added a project: clang.
sberg requested review of this revision.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D87030

Files:
  clang/lib/AST/Expr.cpp
  clang/unittests/Tooling/CastExprTest.cpp


Index: clang/unittests/Tooling/CastExprTest.cpp
===
--- clang/unittests/Tooling/CastExprTest.cpp
+++ clang/unittests/Tooling/CastExprTest.cpp
@@ -34,4 +34,23 @@
 "S1 f(S2 s) { return static_cast(s); }\n");
 }
 
+// Verify that getSubExprAsWritten looks through a ConstantExpr in a scenario
+// like
+//
+//   CXXFunctionalCastExpr functional cast to struct S 
+//   `-ConstantExpr 'S'
+// |-value: Struct
+// `-CXXConstructExpr 'S' 'void (int)'
+//   `-IntegerLiteral 'int' 0
+TEST(CastExprTest, GetSubExprAsWrittenThroughConstantExpr) {
+  CastExprVisitor Visitor;
+  Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) {
+auto Sub = Expr->getSubExprAsWritten();
+EXPECT_TRUE(isa(Sub))
+<< "Expected IntegerLiteral, but saw " << Sub->getStmtClassName();
+  };
+  Visitor.runOver("struct S { consteval S(int) {} };\n"
+  "S f() { return S(0); }\n",
+  CastExprVisitor::Lang_CXX2a);
+}
 }
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1823,8 +1823,8 @@
 // Conversions by constructor and conversion functions have a
 // subexpression describing the call; strip it off.
 if (E->getCastKind() == CK_ConstructorConversion)
-  SubExpr =
-skipImplicitTemporary(cast(SubExpr)->getArg(0));
+  SubExpr = skipImplicitTemporary(
+  cast(SubExpr->IgnoreImplicit())->getArg(0));
 else if (E->getCastKind() == CK_UserDefinedConversion) {
   assert((isa(SubExpr) ||
   isa(SubExpr)) &&


Index: clang/unittests/Tooling/CastExprTest.cpp
===
--- clang/unittests/Tooling/CastExprTest.cpp
+++ clang/unittests/Tooling/CastExprTest.cpp
@@ -34,4 +34,23 @@
 "S1 f(S2 s) { return static_cast(s); }\n");
 }
 
+// Verify that getSubExprAsWritten looks through a ConstantExpr in a scenario
+// like
+//
+//   CXXFunctionalCastExpr functional cast to struct S 
+//   `-ConstantExpr 'S'
+// |-value: Struct
+// `-CXXConstructExpr 'S' 'void (int)'
+//   `-IntegerLiteral 'int' 0
+TEST(CastExprTest, GetSubExprAsWrittenThroughConstantExpr) {
+  CastExprVisitor Visitor;
+  Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) {
+auto Sub = Expr->getSubExprAsWritten();
+EXPECT_TRUE(isa(Sub))
+<< "Expected IntegerLiteral, but saw " << Sub->getStmtClassName();
+  };
+  Visitor.runOver("struct S { consteval S(int) {} };\n"
+  "S f() { return S(0); }\n",
+  CastExprVisitor::Lang_CXX2a);
+}
 }
Index: clang/lib/AST/Expr.cpp
===
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1823,8 +1823,8 @@
 // Conversions by constructor and conversion functions have a
 // subexpression describing the call; strip it off.
 if (E->getCastKind() == CK_ConstructorConversion)
-  SubExpr =
-skipImplicitTemporary(cast(SubExpr)->getArg(0));
+  SubExpr = skipImplicitTemporary(
+  cast(SubExpr->IgnoreImplicit())->getArg(0));
 else if (E->getCastKind() == CK_UserDefinedConversion) {
   assert((isa(SubExpr) ||
   isa(SubExpr)) &&
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87030: Adapt CastExpr::getSubExprAsWritten to ConstantExpr

2020-09-02 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

I hit this with a call to getSubExprAsWriten from the LibreOffice Clang plugin, 
have no idea whether it can be hit from within the compiler itself.  Not sure 
if clang/unittests/Tooling/CastExprTest.cpp is the best place to add a test for 
it.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87030/new/

https://reviews.llvm.org/D87030

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


[PATCH] D87030: Adapt CastExpr::getSubExprAsWritten to ConstantExpr

2020-12-16 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

Ping; OK to submit?  (I meanwhile also get this when compiling some code with 
plain Clang, not just with the LibreOffice Clang plugin where I saw it 
originally.)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87030/new/

https://reviews.llvm.org/D87030

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


[PATCH] D87030: Adapt CastExpr::getSubExprAsWritten to ConstantExpr

2020-10-02 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

friendly ping


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87030/new/

https://reviews.llvm.org/D87030

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


[PATCH] D89481: [scan-build] Fix clang++ pathname again

2020-10-15 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added reviewers: aadg, dcoughlin.
Herald added a subscriber: Charusso.
Herald added a project: clang.
sberg requested review of this revision.

e00629f777d9d62875730f40d266727df300dbb2 "[scan-build] Fix clang++ pathname" had
removed the -MAJOR.MINOR suffix, but since presumably LLVM 7 the suffix is only
-MAJOR, so ClangCXX (i.e., the CLANG_CXX environment variable passed to
clang/tools/scan-build/libexec/ccc-analyzer) now contained a non-existing
/path/to/clang-12++ (which apparently went largely unnoticed as
clang/tools/scan-build/libexec/ccc-analyzer falls back to just 'clang++' if the
executable denoted by CLANG_CXX does not exist).


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D89481

Files:
  clang/tools/scan-build/bin/scan-build


Index: clang/tools/scan-build/bin/scan-build
===
--- clang/tools/scan-build/bin/scan-build
+++ clang/tools/scan-build/bin/scan-build
@@ -1925,7 +1925,7 @@
 $ClangCXX =~ s/.exe$/++.exe/;
   }
   else {
-$ClangCXX =~ s/\-\d+\.\d+$//;
+$ClangCXX =~ s/\-\d+(\.\d+)?$//;
 $ClangCXX .= "++";
   }
 }


Index: clang/tools/scan-build/bin/scan-build
===
--- clang/tools/scan-build/bin/scan-build
+++ clang/tools/scan-build/bin/scan-build
@@ -1925,7 +1925,7 @@
 $ClangCXX =~ s/.exe$/++.exe/;
   }
   else {
-$ClangCXX =~ s/\-\d+\.\d+$//;
+$ClangCXX =~ s/\-\d+(\.\d+)?$//;
 $ClangCXX .= "++";
   }
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87030: Adapt CastExpr::getSubExprAsWritten to ConstantExpr

2020-10-27 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

ping


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87030/new/

https://reviews.llvm.org/D87030

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


[PATCH] D89481: [scan-build] Fix clang++ pathname again

2020-10-27 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

ping


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D89481/new/

https://reviews.llvm.org/D89481

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


[PATCH] D89481: [scan-build] Fix clang++ pathname again

2020-10-28 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg updated this revision to Diff 301273.
sberg edited the summary of this revision.
sberg added a comment.

Is there a reason why "NoQ accepted this revision." kept this at "Needs Review" 
rather than moving it to "This revision is now accepted and ready to land."?

Anyway, I added a test now.  Hope the use of `REQUIRES: shell` is appropriate 
guarding for using `sh` and `basename` (and as such would subsume the `// 
FIXME: Actually, "perl". REQUIRES: shell` found in other test files in that 
directory using `%scan-build`, or should it better also carry that FIXME 
comment for a perl requirement, as scan-build is written in perl?).  (I didn't 
find out how `'shell'` gets added to `available_features` for these tests.  I 
only found it in `clang-tools-extra/test/lit.cfg.py` and 
`compiler-rt/test/lit.common.cfg.py`, but which should not be relevant here?  
Also, I didn't manage to verify this doesn't break anything on Windows; while 
my Linux build dir (at least after once having done `cmake --build . --target 
check-all`) has a `tools/clang/test/Analysis/scan-build` dir that I can test 
with `bin/llvm-lit -v tools/clang/test/Analysis/scan-build`, I don't get that 
directory at all on Windows.)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D89481/new/

https://reviews.llvm.org/D89481

Files:
  clang/test/Analysis/scan-build/cxx-name.test
  clang/test/Analysis/scan-build/lit.local.cfg
  clang/tools/scan-build/bin/scan-build


Index: clang/tools/scan-build/bin/scan-build
===
--- clang/tools/scan-build/bin/scan-build
+++ clang/tools/scan-build/bin/scan-build
@@ -1925,7 +1925,7 @@
 $ClangCXX =~ s/.exe$/++.exe/;
   }
   else {
-$ClangCXX =~ s/\-\d+\.\d+$//;
+$ClangCXX =~ s/\-\d+(\.\d+)?$//;
 $ClangCXX .= "++";
   }
 }
Index: clang/test/Analysis/scan-build/lit.local.cfg
===
--- clang/test/Analysis/scan-build/lit.local.cfg
+++ clang/test/Analysis/scan-build/lit.local.cfg
@@ -15,4 +15,4 @@
 'tools',
 'scan-build',
 'bin')),
- config.clang)))
+ os.path.realpath(config.clang
Index: clang/test/Analysis/scan-build/cxx-name.test
===
--- /dev/null
+++ clang/test/Analysis/scan-build/cxx-name.test
@@ -0,0 +1,9 @@
+REQUIRES: shell
+
+RUN: %scan-build sh -c 'echo "CLANG_CXX=/$(basename "$CLANG_CXX")/"' | 
FileCheck %s
+
+Check that scan-build sets the CLANG_CXX environment variable (meant to be
+consumed by ccc-analyzer) to an appropriate pathname for the clang++ 
executable,
+derived from the pathname of the clang executable:
+
+CHECK: CLANG_CXX=/clang++{{(\.exe)?}}/


Index: clang/tools/scan-build/bin/scan-build
===
--- clang/tools/scan-build/bin/scan-build
+++ clang/tools/scan-build/bin/scan-build
@@ -1925,7 +1925,7 @@
 $ClangCXX =~ s/.exe$/++.exe/;
   }
   else {
-$ClangCXX =~ s/\-\d+\.\d+$//;
+$ClangCXX =~ s/\-\d+(\.\d+)?$//;
 $ClangCXX .= "++";
   }
 }
Index: clang/test/Analysis/scan-build/lit.local.cfg
===
--- clang/test/Analysis/scan-build/lit.local.cfg
+++ clang/test/Analysis/scan-build/lit.local.cfg
@@ -15,4 +15,4 @@
 'tools',
 'scan-build',
 'bin')),
- config.clang)))
+ os.path.realpath(config.clang
Index: clang/test/Analysis/scan-build/cxx-name.test
===
--- /dev/null
+++ clang/test/Analysis/scan-build/cxx-name.test
@@ -0,0 +1,9 @@
+REQUIRES: shell
+
+RUN: %scan-build sh -c 'echo "CLANG_CXX=/$(basename "$CLANG_CXX")/"' | FileCheck %s
+
+Check that scan-build sets the CLANG_CXX environment variable (meant to be
+consumed by ccc-analyzer) to an appropriate pathname for the clang++ executable,
+derived from the pathname of the clang executable:
+
+CHECK: CLANG_CXX=/clang++{{(\.exe)?}}/
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D89481: [scan-build] Fix clang++ pathname again

2020-11-02 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG7a5184ed951a: [scan-build] Fix clang++ pathname again 
(authored by sberg).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D89481/new/

https://reviews.llvm.org/D89481

Files:
  clang/test/Analysis/scan-build/cxx-name.test
  clang/test/Analysis/scan-build/lit.local.cfg
  clang/tools/scan-build/bin/scan-build


Index: clang/tools/scan-build/bin/scan-build
===
--- clang/tools/scan-build/bin/scan-build
+++ clang/tools/scan-build/bin/scan-build
@@ -1925,7 +1925,7 @@
 $ClangCXX =~ s/.exe$/++.exe/;
   }
   else {
-$ClangCXX =~ s/\-\d+\.\d+$//;
+$ClangCXX =~ s/\-\d+(\.\d+)?$//;
 $ClangCXX .= "++";
   }
 }
Index: clang/test/Analysis/scan-build/lit.local.cfg
===
--- clang/test/Analysis/scan-build/lit.local.cfg
+++ clang/test/Analysis/scan-build/lit.local.cfg
@@ -15,4 +15,4 @@
 'tools',
 'scan-build',
 'bin')),
- config.clang)))
+ os.path.realpath(config.clang
Index: clang/test/Analysis/scan-build/cxx-name.test
===
--- /dev/null
+++ clang/test/Analysis/scan-build/cxx-name.test
@@ -0,0 +1,9 @@
+REQUIRES: shell
+
+RUN: %scan-build sh -c 'echo "CLANG_CXX=/$(basename "$CLANG_CXX")/"' | 
FileCheck %s
+
+Check that scan-build sets the CLANG_CXX environment variable (meant to be
+consumed by ccc-analyzer) to an appropriate pathname for the clang++ 
executable,
+derived from the pathname of the clang executable:
+
+CHECK: CLANG_CXX=/clang++{{(\.exe)?}}/


Index: clang/tools/scan-build/bin/scan-build
===
--- clang/tools/scan-build/bin/scan-build
+++ clang/tools/scan-build/bin/scan-build
@@ -1925,7 +1925,7 @@
 $ClangCXX =~ s/.exe$/++.exe/;
   }
   else {
-$ClangCXX =~ s/\-\d+\.\d+$//;
+$ClangCXX =~ s/\-\d+(\.\d+)?$//;
 $ClangCXX .= "++";
   }
 }
Index: clang/test/Analysis/scan-build/lit.local.cfg
===
--- clang/test/Analysis/scan-build/lit.local.cfg
+++ clang/test/Analysis/scan-build/lit.local.cfg
@@ -15,4 +15,4 @@
 'tools',
 'scan-build',
 'bin')),
- config.clang)))
+ os.path.realpath(config.clang
Index: clang/test/Analysis/scan-build/cxx-name.test
===
--- /dev/null
+++ clang/test/Analysis/scan-build/cxx-name.test
@@ -0,0 +1,9 @@
+REQUIRES: shell
+
+RUN: %scan-build sh -c 'echo "CLANG_CXX=/$(basename "$CLANG_CXX")/"' | FileCheck %s
+
+Check that scan-build sets the CLANG_CXX environment variable (meant to be
+consumed by ccc-analyzer) to an appropriate pathname for the clang++ executable,
+derived from the pathname of the clang executable:
+
+CHECK: CLANG_CXX=/clang++{{(\.exe)?}}/
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D87030: Adapt CastExpr::getSubExprAsWritten to ConstantExpr

2020-11-02 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

ping


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D87030/new/

https://reviews.llvm.org/D87030

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


[PATCH] D90572: [clang] [MinGW] Allow using the vptr sanitizer

2020-11-03 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

Smells like this breaks various bots due to a -fsanitize=...,... option now 
listing 18 instead of 17 items, see 
http://lab.llvm.org:8011/#builders/76/builds/363, 
http://lab.llvm.org:8011/#builders/93/builds/430, 
http://lab.llvm.org:8011/#builders/66/builds/315, 
http://lab.llvm.org:8011/#builders/7/builds/303.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D90572/new/

https://reviews.llvm.org/D90572

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


[PATCH] D100581: [Clang] -Wunused-but-set-parameter and -Wunused-but-set-variable

2021-06-03 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

Is it intentional that this warns about volatile variables as in

  void f(char * p) {
  volatile char c = 0;
  c ^= *p;
  }

(I see that GCC warns about volatile too, at least when you replace the `^=` 
with `=`, so assume the answer is "yes", but would just like to see that 
confirmed (ideally with a test case even?).)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D100581/new/

https://reviews.llvm.org/D100581

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


[PATCH] D110310: State the kind of VerifyDiagnosticConsumer regex syntax (NFC)

2021-09-22 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added a project: clang.
sberg requested review of this revision.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D110310

Files:
  clang/include/clang/Frontend/VerifyDiagnosticConsumer.h


Index: clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
===
--- clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -157,7 +157,8 @@
 /// In this example, the diagnostic may appear only once, if at all.
 ///
 /// Regex matching mode may be selected by appending '-re' to type and
-/// including regexes wrapped in double curly braces in the directive, such as:
+/// including regexes (using POSIX extended regular expression syntax) wrapped
+/// in double curly braces in the directive, such as:
 ///
 /// \code
 ///   expected-error-re {{format specifies type 'wchar_t **' (aka '{{.+}}')}}


Index: clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
===
--- clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
+++ clang/include/clang/Frontend/VerifyDiagnosticConsumer.h
@@ -157,7 +157,8 @@
 /// In this example, the diagnostic may appear only once, if at all.
 ///
 /// Regex matching mode may be selected by appending '-re' to type and
-/// including regexes wrapped in double curly braces in the directive, such as:
+/// including regexes (using POSIX extended regular expression syntax) wrapped
+/// in double curly braces in the directive, such as:
 ///
 /// \code
 ///   expected-error-re {{format specifies type 'wchar_t **' (aka '{{.+}}')}}
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103949: Only consider built-in compound assignment operators for -Wunused-but-set-*

2021-06-09 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg created this revision.
sberg added a reviewer: mbenfield.
sberg added a project: clang.
sberg requested review of this revision.

At least LibreOffice has, for mainly historic reasons that would be hard to 
change now, a class `Any` with an overloaded `operator >>=` that semantically 
does not assign to the LHS but rather extracts into the (by-reference) RHS.  
Which thus caused false positive `-Wunused-but-set-parameter` and 
`-Wunused-but-set-variable` after those have been introduced recently.
This change is more conservative about the assumed semantics of overloaded 
operators, excluding compound assignment operators but keeping plain `operator 
=` ones.  At least for LibreOffice, that strikes a good balance of not 
producing false positives but still finding lots of true ones.


https://reviews.llvm.org/D103949

Files:
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp


Index: clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
===
--- clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
+++ clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
@@ -6,6 +6,7 @@
 
 struct __attribute__((warn_unused)) SWarnUnused {
   int j;
+  void operator +=(int);
 };
 
 int f0() {
@@ -48,3 +49,16 @@
   char a[x];
   char b[y];
 }
+
+void f3(int n) {
+  // Don't warn for overloaded compound assignment operators.
+  SWarnUnused swu;
+  swu += n;
+}
+
+template void f4(T n) {
+  // Don't warn for (potentially) overloaded compound assignment operators in
+  // template code.
+  SWarnUnused swu;
+  swu += n;
+}
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -7791,11 +7791,16 @@
 Expr *E, llvm::DenseMap &RefsMinusAssignments) {
   DeclRefExpr *LHS = nullptr;
   if (BinaryOperator *BO = dyn_cast(E)) {
-if (!BO->isAssignmentOp())
+if (BO->getLHS()->getType()->isDependentType() ||
+BO->getRHS()->getType()->isDependentType())
+{
+  if (BO->getOpcode() != BO_Assign)
+return;
+} else if (!BO->isAssignmentOp())
   return;
 LHS = dyn_cast(BO->getLHS());
   } else if (CXXOperatorCallExpr *COCE = dyn_cast(E)) {
-if (!COCE->isAssignmentOp())
+if (COCE->getOperator() != OO_Equal)
   return;
 LHS = dyn_cast(COCE->getArg(0));
   }


Index: clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
===
--- clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
+++ clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
@@ -6,6 +6,7 @@
 
 struct __attribute__((warn_unused)) SWarnUnused {
   int j;
+  void operator +=(int);
 };
 
 int f0() {
@@ -48,3 +49,16 @@
   char a[x];
   char b[y];
 }
+
+void f3(int n) {
+  // Don't warn for overloaded compound assignment operators.
+  SWarnUnused swu;
+  swu += n;
+}
+
+template void f4(T n) {
+  // Don't warn for (potentially) overloaded compound assignment operators in
+  // template code.
+  SWarnUnused swu;
+  swu += n;
+}
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -7791,11 +7791,16 @@
 Expr *E, llvm::DenseMap &RefsMinusAssignments) {
   DeclRefExpr *LHS = nullptr;
   if (BinaryOperator *BO = dyn_cast(E)) {
-if (!BO->isAssignmentOp())
+if (BO->getLHS()->getType()->isDependentType() ||
+BO->getRHS()->getType()->isDependentType())
+{
+  if (BO->getOpcode() != BO_Assign)
+return;
+} else if (!BO->isAssignmentOp())
   return;
 LHS = dyn_cast(BO->getLHS());
   } else if (CXXOperatorCallExpr *COCE = dyn_cast(E)) {
-if (!COCE->isAssignmentOp())
+if (COCE->getOperator() != OO_Equal)
   return;
 LHS = dyn_cast(COCE->getArg(0));
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D103949: Only consider built-in compound assignment operators for -Wunused-but-set-*

2021-06-09 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

In D103949#2807490 , @xbolva00 wrote:

> gcc also ignores it?

For reasons that I never looked into, GCC never warned for any of these cases.  
The Clang implementation appears to be way more aggressive (in a positive 
sense) to begin with.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103949/new/

https://reviews.llvm.org/D103949

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


[PATCH] D103623: [Clang] Test case for -Wunused-but-set-variable, warn for volatile.

2021-06-09 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg accepted this revision.
sberg added a comment.
This revision is now accepted and ready to land.

LGTM


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103623/new/

https://reviews.llvm.org/D103623

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


[PATCH] D103949: Only consider built-in compound assignment operators for -Wunused-but-set-*

2021-06-09 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added inline comments.



Comment at: clang/lib/Sema/SemaExprCXX.cpp:7794-7798
+if (BO->getLHS()->getType()->isDependentType() ||
+BO->getRHS()->getType()->isDependentType())
+{
+  if (BO->getOpcode() != BO_Assign)
+return;

mbenfield wrote:
> Would you mind elaborating on the need for this code? IIUC, you're concerned 
> about overloaded operators, but won't such operators always be covered by the 
> `CXXOperatorCallExpr` case below? 
That's what I would initially have thought too (see my unanswered 
 "[llvm-dev] 
BinaryOperator vs. CXXOperatorCallExpr in template code"; but which, I notice 
now, I accidentally sent to llvm-dev rather than cfe-dev).

But e.g. the template `f4` test code in `warn-unused-but-set-variables-cpp.cpp` 
turns the `+=` into a `BinaryOperator`.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103949/new/

https://reviews.llvm.org/D103949

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


[PATCH] D103949: Only consider built-in compound assignment operators for -Wunused-but-set-*

2021-06-13 Thread Stephan Bergmann via Phabricator via cfe-commits
This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rGb5b9489b2415: Only consider built-in compound assignment 
operators for -Wunused-but-set-* (authored by sberg).

Changed prior to commit:
  https://reviews.llvm.org/D103949?vs=350824&id=351778#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D103949/new/

https://reviews.llvm.org/D103949

Files:
  clang/lib/Sema/SemaExprCXX.cpp
  clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp


Index: clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
===
--- clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
+++ clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
@@ -6,6 +6,7 @@
 
 struct __attribute__((warn_unused)) SWarnUnused {
   int j;
+  void operator +=(int);
 };
 
 int f0() {
@@ -48,3 +49,16 @@
   char a[x];
   char b[y];
 }
+
+void f3(int n) {
+  // Don't warn for overloaded compound assignment operators.
+  SWarnUnused swu;
+  swu += n;
+}
+
+template void f4(T n) {
+  // Don't warn for (potentially) overloaded compound assignment operators in
+  // template code.
+  SWarnUnused swu;
+  swu += n;
+}
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -7808,11 +7808,15 @@
 Expr *E, llvm::DenseMap &RefsMinusAssignments) {
   DeclRefExpr *LHS = nullptr;
   if (BinaryOperator *BO = dyn_cast(E)) {
-if (!BO->isAssignmentOp())
+if (BO->getLHS()->getType()->isDependentType() ||
+BO->getRHS()->getType()->isDependentType()) {
+  if (BO->getOpcode() != BO_Assign)
+return;
+} else if (!BO->isAssignmentOp())
   return;
 LHS = dyn_cast(BO->getLHS());
   } else if (CXXOperatorCallExpr *COCE = dyn_cast(E)) {
-if (!COCE->isAssignmentOp())
+if (COCE->getOperator() != OO_Equal)
   return;
 LHS = dyn_cast(COCE->getArg(0));
   }


Index: clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
===
--- clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
+++ clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
@@ -6,6 +6,7 @@
 
 struct __attribute__((warn_unused)) SWarnUnused {
   int j;
+  void operator +=(int);
 };
 
 int f0() {
@@ -48,3 +49,16 @@
   char a[x];
   char b[y];
 }
+
+void f3(int n) {
+  // Don't warn for overloaded compound assignment operators.
+  SWarnUnused swu;
+  swu += n;
+}
+
+template void f4(T n) {
+  // Don't warn for (potentially) overloaded compound assignment operators in
+  // template code.
+  SWarnUnused swu;
+  swu += n;
+}
Index: clang/lib/Sema/SemaExprCXX.cpp
===
--- clang/lib/Sema/SemaExprCXX.cpp
+++ clang/lib/Sema/SemaExprCXX.cpp
@@ -7808,11 +7808,15 @@
 Expr *E, llvm::DenseMap &RefsMinusAssignments) {
   DeclRefExpr *LHS = nullptr;
   if (BinaryOperator *BO = dyn_cast(E)) {
-if (!BO->isAssignmentOp())
+if (BO->getLHS()->getType()->isDependentType() ||
+BO->getRHS()->getType()->isDependentType()) {
+  if (BO->getOpcode() != BO_Assign)
+return;
+} else if (!BO->isAssignmentOp())
   return;
 LHS = dyn_cast(BO->getLHS());
   } else if (CXXOperatorCallExpr *COCE = dyn_cast(E)) {
-if (!COCE->isAssignmentOp())
+if (COCE->getOperator() != OO_Equal)
   return;
 LHS = dyn_cast(COCE->getArg(0));
   }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D99005: [clang] Implement P2266 Simpler implicit move

2021-06-14 Thread Stephan Bergmann via Phabricator via cfe-commits
sberg added a comment.

(In a build prior to 
https://reviews.llvm.org/rGc60dd3b2626a4d9eefd9f82f9a406b0d28d3fd72 "Revert 
'[clang] NRVO: Improvements and handling of more cases.'") I see the following 
(reduced from 
https://git.libreoffice.org/core/+/649313625b94e6b879848fc19b607b74375100bf/o3tl/qa/compile-temporary.cxx)
 started to fail under `-std=c++2b` with this change (and continues to compile 
fine with `-std=c++20`):

  $ cat test.cc
  template  constexpr T& temporary(T&& x) { return x; }
  template  constexpr T& temporary(T&) = delete;
  void f(int*);
  int g();
  void h()
  {
  f(&temporary(int()));
  f(&temporary(g()));
  }
  
  $ clang++ -std=c++2b -fsyntax-only test.cc
  test.cc:1:62: error: non-const lvalue reference to type 'int' cannot bind to 
a temporary of type 'int'
  template  constexpr T& temporary(T&& x) { return x; }
   ^
  test.cc:7:8: note: in instantiation of function template specialization 
'temporary' requested here
  f(&temporary(int()));
 ^
  test.cc:8:8: error: no matching function for call to 'temporary'
  f(&temporary(g()));
 ^
  test.cc:2:36: note: candidate function [with T = int] not viable: expects an 
lvalue for 1st argument
  template  constexpr T& temporary(T&) = delete;
 ^
  test.cc:1:36: note: candidate template ignored: substitution failure [with T 
= int]
  template  constexpr T& temporary(T&& x) { return x; }
 ^
  2 errors generated.

It is not clear to me whether that is an intended change in behavior according 
to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2266r1.html 
"Simpler implicit move", or whether it is a bug in this implementation.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D99005/new/

https://reviews.llvm.org/D99005

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


  1   2   >