[PATCH] D71397: [clang] Improve LLVM-style RTTI support in ExternalASTSource/ExternalSemaSource

2019-12-15 Thread Lang Hames via Phabricator via cfe-commits
lhames added a comment.

In D71397#1784325 , @teemperor wrote:

> I would prefer landing this as-is because it is just doing the same we do in 
> other places in LLVM. Afterwards migrating the whole RTTI system in LLVM to a 
> new system (whether that will be D39111  or 
> just a ClassID type) sounds good to me.


Yep -- To be clear I didn't raise D39111  as 
an objection to this approach, just as a matter of interest. As you noted it 
should be easy to switch later.


Repository:
  rC Clang

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

https://reviews.llvm.org/D71397



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


[PATCH] D71433: [analyzer] CERT: POS34-C

2019-12-15 Thread Zurab Tsinadze via Phabricator via cfe-commits
zukatsinadze updated this revision to Diff 233955.
zukatsinadze added a comment.

- Removed extra test
- Used `CallDescription` for checking call.




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

https://reviews.llvm.org/D71433

Files:
  clang/docs/analyzer/checkers.rst
  clang/include/clang/StaticAnalyzer/Checkers/Checkers.td
  clang/include/clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h
  clang/lib/StaticAnalyzer/Checkers/AllocationState.h
  clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt
  clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/cert/PutenvWithAutoChecker.cpp
  clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
  clang/test/Analysis/cert/pos34-c-fp-suppression.cpp
  clang/test/Analysis/cert/pos34-c.cpp

Index: clang/test/Analysis/cert/pos34-c.cpp
===
--- /dev/null
+++ clang/test/Analysis/cert/pos34-c.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=alpha.security.cert.pos.34c\
+// RUN:  -verify %s
+
+// Examples from the CERT rule's page.
+// https://wiki.sei.cmu.edu/confluence/display/c/POS34-C.+Do+not+call+putenv%28%29+with+a+pointer+to+an+automatic+variable+as+the+argument
+
+#include "../Inputs/system-header-simulator.h"
+void free(void *memblock);
+void *malloc(size_t size);
+int putenv(char *);
+int snprintf(char *str, size_t size, const char *format, ...);
+
+namespace test_auto_var_used_bad {
+
+int volatile_memory1(const char *var) {
+  char env[1024];
+  int retval = snprintf(env, sizeof(env), "TEST=%s", var);
+  if (retval < 0 || (size_t)retval >= sizeof(env)) {
+/* Handle error */
+  }
+
+  return putenv(env);
+  // expected-warning@-1 {{'putenv' function should not be called with auto variables}}
+}
+
+} // namespace test_auto_var_used_bad
+
+namespace test_auto_var_used_good {
+
+int test_static(const char *var) {
+  static char env[1024];
+
+  int retval = snprintf(env, sizeof(env), "TEST=%s", var);
+  if (retval < 0 || (size_t)retval >= sizeof(env)) {
+/* Handle error */
+  }
+
+  return putenv(env);
+}
+
+int test_heap_memory(const char *var) {
+  static char *oldenv;
+  const char *env_format = "TEST=%s";
+  const size_t len = strlen(var) + strlen(env_format);
+  char *env = (char *)malloc(len);
+  if (env == NULL) {
+return -1;
+  }
+  if (putenv(env) != 0) { // no-warning: env was dynamically allocated.
+free(env);
+return -1;
+  }
+  if (oldenv != NULL) {
+free(oldenv); /* avoid memory leak */
+  }
+  oldenv = env;
+  return 0;
+}
+
+} // namespace test_auto_var_used_good
Index: clang/test/Analysis/cert/pos34-c-fp-suppression.cpp
===
--- /dev/null
+++ clang/test/Analysis/cert/pos34-c-fp-suppression.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_analyze_cc1 \
+// RUN:  -analyzer-checker=alpha.security.cert.pos.34c\
+// RUN:  -verify %s
+
+#include "../Inputs/system-header-simulator.h"
+void free(void *memblock);
+void *malloc(size_t size);
+int putenv(char *);
+int rand();
+
+namespace test_auto_var_used_good {
+
+extern char *ex;
+int test_extern() {
+  return putenv(ex); // no-warning: extern storage class.
+}
+
+void foo(void) {
+  char *buffer = (char *)"huttah!";
+  if (rand() % 2 == 0) {
+buffer = (char *)malloc(5);
+strcpy(buffer, "woot");
+  }
+  putenv(buffer);
+}
+
+void bar(void) {
+  char *buffer = (char *)malloc(5);
+  strcpy(buffer, "woot");
+
+  if (rand() % 2 == 0) {
+free(buffer);
+buffer = (char *)"blah blah blah";
+  }
+  putenv(buffer);
+}
+
+void baz() {
+  char env[] = "NAME=value";
+  // TODO: False Positive
+  putenv(env);
+  // expected-warning@-1 {{'putenv' function should not be called with auto variables}}
+
+  /*
+DO SOMETHING
+  */
+
+  putenv((char *)"NAME=anothervalue");
+}
+
+} // namespace test_auto_var_used_good
Index: clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
===
--- clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
+++ clang/lib/StaticAnalyzer/Core/CommonBugCategories.cpp
@@ -9,13 +9,18 @@
 #include "clang/StaticAnalyzer/Core/BugReporter/CommonBugCategories.h"
 
 // Common strings used for the "category" of many static analyzer issues.
-namespace clang { namespace ento { namespace categories {
+namespace clang {
+namespace ento {
+namespace categories {
 
-const char * const CoreFoundationObjectiveC = "Core Foundation/Objective-C";
-const char * const LogicError = "Logic error";
-const char * const MemoryRefCount =
-  "Memory (Core Foundation/Objective-C/OSObject)";
-const char * const MemoryError = "Memory error";
-const char * const UnixAPI = "Unix API";
-const char * const CXXObjectLifecycle = "C++ object lifecycle";
-}}}
+const char *const CoreFoundationObjectiveC = "Core Foundation/Objective-C";
+const char *const LogicError = "Logic error";
+const char *const MemoryRefCount =
+"Memory (

[PATCH] D71026: Fix LLVM_ENABLE_MODULES=ON + BUILD_SHARED_LIBS=ON build

2019-12-15 Thread Alexander Richardson via Phabricator via cfe-commits
arichardson added a comment.

If I build on macOS with `cmake -GNinja -DBUILD_SHARED_LIBS=ON 
-DCMAKE_BUILD_TYPE=Debug 
-DLLVM_ENABLE_PROJECTS=llvm;clang;lld;compiler-rt;libcxx;libcxxabi 
-DBUILD_SHARED_LIBS=ON -DLLVM_ENABLE_MODULES=ON`, I get lots of linker errors 
building e.g. libclangASTDiff.dylib due to using the internal ASTMatchers 
header inside the Tooling/Transformer headers.

This is probably due to https://bugs.llvm.org/show_bug.cgi?id=23521 mentioned 
in the previous commits that added the exclude directives.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71026



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


[PATCH] D71020: [ASTImporter] Friend class decl should not be visible in its context

2019-12-15 Thread Aleksei Sidorin via Phabricator via cfe-commits
a_sidorin added a comment.

Hi Gabor,
I have an inline comment for the patch. Otherwise, looks good.




Comment at: clang/unittests/AST/ASTImporterTest.cpp:252
+  QualType Ty = FD->getFriendType()->getType().getCanonicalType();
+  if (isa(Ty))
+Ty = cast(Ty)->getNamedType();

I wonder if ElaboratedType can be a canonical type because it is only a sugar 
type itself. Do we need to handle this case?


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71020



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


[PATCH] D64128: [CodeGen] Generate llvm.ptrmask instead of inttoptr(and(ptrtoint, C)) if possible.

2019-12-15 Thread Alexander Richardson via Phabricator via cfe-commits
arichardson added a comment.

In D64128#1576391 , @rjmccall wrote:

> I wouldn't favor adding something really obscure that was only useful for 
> clang, but I think builtins to set and clear mask bits while promising to 
> preserve object-reference identity would be more generally useful for 
> libraries.  For example, there might be somewhere in libc++ that could take 
> advantage of this.


This would be very useful for CHERI since in our architecture pointers 
(capabilties) carry provenance information at runtime.
The bitwise operations used by default sometimes make it unclear which 
provenance we should should use:  should the resulting value be a capability 
derived from the LHS or RHS?
Checking the value of low bits is especially awkward since it that case we 
would expect the result to be an invalid uintptr_t (derived from NULL instead 
of the LHS/RHS uintptr_t).


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D64128



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


[clang] 273e674 - [analyzer] Add support for namespaces to GenericTaintChecker

2019-12-15 Thread Borsik Gabor via cfe-commits

Author: Borsik Gabor
Date: 2019-12-15T12:11:22+01:00
New Revision: 273e67425243c74b33d24aa5b2c574877cc3e9bb

URL: 
https://github.com/llvm/llvm-project/commit/273e67425243c74b33d24aa5b2c574877cc3e9bb
DIFF: 
https://github.com/llvm/llvm-project/commit/273e67425243c74b33d24aa5b2c574877cc3e9bb.diff

LOG: [analyzer] Add support for namespaces to GenericTaintChecker

This patch introduces the namespaces for the configured functions and
also enables the use of the member functions.

I added an optional Scope field for every configured function. Functions
without Scope match for every function regardless of the namespace.
Functions with Scope will match if the full name of the function starts
with the Scope.
Multiple functions can exist with the same name.

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

Added: 
clang/test/Analysis/taint-generic.cpp

Modified: 
clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
clang/test/Analysis/Inputs/taint-generic-config.yaml

Removed: 




diff  --git a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp 
b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
index 2ceb6313920b..302d5bb1bea8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
@@ -24,9 +24,10 @@
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
-#include "llvm/ADT/StringMap.h"
 #include "llvm/Support/YAMLTraits.h"
+#include 
 #include 
+#include 
 #include 
 
 using namespace clang;
@@ -56,10 +57,11 @@ class GenericTaintChecker
 
   /// Used to parse the configuration file.
   struct TaintConfiguration {
-using NameArgsPair = std::pair;
+using NameScopeArgs = std::tuple;
 
 struct Propagation {
   std::string Name;
+  std::string Scope;
   ArgVector SrcArgs;
   SignedArgVector DstArgs;
   VariadicType VarType;
@@ -67,8 +69,8 @@ class GenericTaintChecker
 };
 
 std::vector Propagations;
-std::vector Filters;
-std::vector Sinks;
+std::vector Filters;
+std::vector Sinks;
 
 TaintConfiguration() = default;
 TaintConfiguration(const TaintConfiguration &) = default;
@@ -97,18 +99,49 @@ class GenericTaintChecker
   BT.reset(new BugType(this, "Use of Untrusted Data", "Untrusted Data"));
   }
 
+  struct FunctionData {
+FunctionData() = delete;
+FunctionData(const FunctionData &) = default;
+FunctionData(FunctionData &&) = default;
+FunctionData &operator=(const FunctionData &) = delete;
+FunctionData &operator=(FunctionData &&) = delete;
+
+static Optional create(const CallExpr *CE,
+ const CheckerContext &C) {
+  const FunctionDecl *FDecl = C.getCalleeDecl(CE);
+  if (!FDecl || (FDecl->getKind() != Decl::Function &&
+ FDecl->getKind() != Decl::CXXMethod))
+return None;
+
+  StringRef Name = C.getCalleeName(FDecl);
+  std::string FullName = FDecl->getQualifiedNameAsString();
+  if (Name.empty() || FullName.empty())
+return None;
+
+  return FunctionData{FDecl, Name, FullName};
+}
+
+bool isInScope(StringRef Scope) const {
+  return StringRef(FullName).startswith(Scope);
+}
+
+const FunctionDecl *const FDecl;
+const StringRef Name;
+const std::string FullName;
+  };
+
   /// Catch taint related bugs. Check if tainted data is passed to a
   /// system call etc. Returns true on matching.
-  bool checkPre(const CallExpr *CE, const FunctionDecl *FDecl, StringRef Name,
+  bool checkPre(const CallExpr *CE, const FunctionData &FData,
 CheckerContext &C) const;
 
   /// Add taint sources on a pre-visit. Returns true on matching.
-  bool addSourcesPre(const CallExpr *CE, const FunctionDecl *FDecl,
- StringRef Name, CheckerContext &C) const;
+  bool addSourcesPre(const CallExpr *CE, const FunctionData &FData,
+ CheckerContext &C) const;
 
   /// Mark filter's arguments not tainted on a pre-visit. Returns true on
   /// matching.
-  bool addFiltersPre(const CallExpr *CE, StringRef Name,
+  bool addFiltersPre(const CallExpr *CE, const FunctionData &FData,
  CheckerContext &C) const;
 
   /// Propagate taint generated at pre-visit. Returns true on matching.
@@ -149,7 +182,7 @@ class GenericTaintChecker
   /// Check if tainted data is used as a custom sink's parameter.
   static constexpr llvm::StringLiteral MsgCustomSink =
   "Untrusted data is passed to a user-defined sink";
-  bool checkCustomSinks(const CallExpr *CE, StringRef Name,
+  bool checkCustomSinks(const CallExpr *CE, const FunctionData &FData,
 CheckerContext &C) const;
 
   /// Generate a report if the e

[PATCH] D70878: [analyzer] Add support for namespaces to GenericTaintChecker

2019-12-15 Thread Borsik Gábor via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
boga95 marked 2 inline comments as done.
Closed by commit rG273e67425243: [analyzer] Add support for namespaces to 
GenericTaintChecker (authored by boga95).

Changed prior to commit:
  https://reviews.llvm.org/D70878?vs=231621&id=233957#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70878

Files:
  clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
  clang/test/Analysis/Inputs/taint-generic-config.yaml
  clang/test/Analysis/taint-generic.cpp

Index: clang/test/Analysis/taint-generic.cpp
===
--- /dev/null
+++ clang/test/Analysis/taint-generic.cpp
@@ -0,0 +1,126 @@
+// RUN: %clang_analyze_cc1  -analyzer-checker=alpha.security.taint,core,alpha.security.ArrayBoundV2 -analyzer-config alpha.security.taint.TaintPropagation:Config=%S/Inputs/taint-generic-config.yaml -Wno-format-security -verify -std=c++11 %s
+
+#define BUFSIZE 10
+int Buffer[BUFSIZE];
+
+int scanf(const char*, ...);
+int mySource1();
+int mySource3();
+
+bool isOutOfRange2(const int*);
+
+void mySink2(int);
+
+// Test configuration
+namespace myNamespace {
+  void scanf(const char*, ...);
+  void myScanf(const char*, ...);
+  int mySource3();
+
+  bool isOutOfRange(const int*);
+  bool isOutOfRange2(const int*);
+
+  void mySink(int, int, int);
+  void mySink2(int);
+}
+
+namespace myAnotherNamespace {
+  int mySource3();
+
+  bool isOutOfRange2(const int*);
+
+  void mySink2(int);
+}
+
+void testConfigurationNamespacePropagation1() {
+  int x;
+  // The built-in functions should be matched only for functions in
+  // the global namespace
+  myNamespace::scanf("%d", &x);
+  Buffer[x] = 1; // no-warning
+
+  scanf("%d", &x);
+  Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
+}
+
+void testConfigurationNamespacePropagation2() {
+  int x = mySource3();
+  Buffer[x] = 1; // no-warning
+
+  int y = myNamespace::mySource3();
+  Buffer[y] = 1; // expected-warning {{Out of bound memory access }}
+}
+
+void testConfigurationNamespacePropagation3() {
+  int x = myAnotherNamespace::mySource3();
+  Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
+}
+
+void testConfigurationNamespacePropagation4() {
+  int x;
+  // Configured functions without scope should match for all function.
+  myNamespace::myScanf("%d", &x);
+  Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
+}
+
+void testConfigurationNamespaceFilter1() {
+  int x = mySource1();
+  if (myNamespace::isOutOfRange2(&x))
+return;
+  Buffer[x] = 1; // no-warning
+
+  int y = mySource1();
+  if (isOutOfRange2(&y))
+return;
+  Buffer[y] = 1; // expected-warning {{Out of bound memory access }}
+}
+
+void testConfigurationNamespaceFilter2() {
+  int x = mySource1();
+  if (myAnotherNamespace::isOutOfRange2(&x))
+return;
+  Buffer[x] = 1; // no-warning
+}
+
+void testConfigurationNamespaceFilter3() {
+  int x = mySource1();
+  if (myNamespace::isOutOfRange(&x))
+return;
+  Buffer[x] = 1; // no-warning
+}
+
+void testConfigurationNamespaceSink1() {
+  int x = mySource1();
+  mySink2(x); // no-warning
+
+  int y = mySource1();
+  myNamespace::mySink2(y);
+  // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
+}
+
+void testConfigurationNamespaceSink2() {
+  int x = mySource1();
+  myAnotherNamespace::mySink2(x);
+  // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
+}
+
+void testConfigurationNamespaceSink3() {
+  int x = mySource1();
+  myNamespace::mySink(x, 0, 1);
+  // expected-warning@-1 {{Untrusted data is passed to a user-defined sink}}
+}
+
+struct Foo {
+void scanf(const char*, int*);
+void myMemberScanf(const char*, int*);
+};
+
+void testConfigurationMemberFunc() {
+  int x;
+  Foo foo;
+  foo.scanf("%d", &x);
+  Buffer[x] = 1; // no-warning
+
+  foo.myMemberScanf("%d", &x);
+  Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
+}
Index: clang/test/Analysis/Inputs/taint-generic-config.yaml
===
--- clang/test/Analysis/Inputs/taint-generic-config.yaml
+++ clang/test/Analysis/Inputs/taint-generic-config.yaml
@@ -9,12 +9,29 @@
   - Name: mySource2
 DstArgs:  [0]
 
+  # int x = myNamespace::mySource3(); // x is tainted
+  - Name: mySource3
+Scope:"myNamespace::"
+DstArgs:  [-1]
+
+  # int x = myAnotherNamespace::mySource3(); // x is tainted
+  - Name: mySource3
+Scope:"myAnotherNamespace::"
+DstArgs:  [-1]
+
   # int x, y;
   # myScanf("%d %d", &x, &y); // x and y are tainted
   - Name:  myScanf
 VariadicType:  Dst
 VariadicIndex: 1
 
+  # int x, y;
+  # Foo::myScanf("%d %d", &x, &y); // x and y are tainted
+  - Name:  myMemberScanf
+Scope: "Foo::"
+VariadicType:  Dst
+VariadicIndex: 1
+
   

[PATCH] D67923: [TLI] Support for per-Function TLI that overrides available libfuncs

2019-12-15 Thread Guillaume Chatelet via Phabricator via cfe-commits
gchatelet accepted this revision.
gchatelet added a comment.

Thx !




Comment at: llvm/include/llvm/Analysis/TargetLibraryInfo.h:227
+  const TargetLibraryInfoImpl &Impl,
+  LLVM_ATTRIBUTE_UNUSED Optional F = None)
+  : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) {

I don't think you need the `LLVM_ATTRIBUTE_UNUSED` here



Comment at: llvm/include/llvm/Analysis/TargetLibraryInfo.h:229
+  : Impl(&Impl), OverrideAsUnavailable(NumLibFuncs) {
+if (F) {
+  if ((*F)->hasFnAttribute("no-builtins"))

[optional] rewrite as `if (!F) return;` to reduce nesting depth.



Comment at: llvm/include/llvm/Analysis/TargetLibraryInfo.h:236
+AttributeSet FnAttrs = (*F)->getAttributes().getFnAttributes();
+std::string Prefix = "no-builtin-";
+for (const Attribute &Attr : FnAttrs) {

Inline so you don't allocate the string (`consumeFront` takes a `StringRef`)


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D67923



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


[PATCH] D71524: [analyzer] Support tainted objects in GenericTaintChecker

2019-12-15 Thread Borsik Gábor via Phabricator via cfe-commits
boga95 created this revision.
boga95 added reviewers: NoQ, Szelethus.
Herald added subscribers: cfe-commits, Charusso, donat.nagy, mikhail.ramalho, 
a.sidorin, szepet, baloghadamsoftware.
Herald added a project: clang.

I extended the supported C++ features:

- The `this` pointer can be tainted (0. argument)
- All `std::basic_istream` objects are tainted unconditionally (`std::cin`, 
`std::ifstream`, etc.)
- `std::getline` and some member function of `std::string` propagates taint
- Extraction operator and copy assignment propagate taint


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71524

Files:
  clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
  clang/lib/StaticAnalyzer/Checkers/Taint.cpp
  clang/test/Analysis/taint-generic.cpp

Index: clang/test/Analysis/taint-generic.cpp
===
--- clang/test/Analysis/taint-generic.cpp
+++ clang/test/Analysis/taint-generic.cpp
@@ -124,3 +124,126 @@
   foo.myMemberScanf("%d", &x);
   Buffer[x] = 1; // expected-warning {{Out of bound memory access }}
 }
+
+
+// Test I/O
+namespace std {
+  template class char_traits {};
+
+  class ios_base {};
+
+  template>
+  class basic_ios : public ios_base {};
+
+  template>
+  class basic_istream : virtual public basic_ios {};
+  template>
+  class basic_ostream : virtual public basic_ios {};
+
+  using istream = basic_istream;
+  using ostream = basic_ostream;
+  using wistream = basic_istream;
+
+  istream& operator>>(istream& is, int& val);
+  wistream& operator>>(wistream& is, int& val);
+
+  extern istream cin;
+  extern istream wcin;
+
+  template>
+  class basic_fstream :
+public basic_istream, public basic_ostream {
+  public:
+  basic_fstream(const char*) {}
+  };
+  template>
+  class basic_ifstream : public basic_istream {
+  public:
+basic_ifstream(const char*) {}
+  };
+
+  using ifstream = basic_ifstream;
+  using fstream = basic_ifstream;
+
+  template class allocator {};
+
+namespace __cxx11 {
+template<
+  class CharT,
+  class Traits = std::char_traits,
+  class Allocator = std::allocator>
+class basic_string {
+public:
+  const char* c_str();
+  basic_string operator=(const basic_string&);
+private:
+  unsigned size;
+  char* ptr;
+};
+  }
+
+  using string = __cxx11::basic_string;
+
+  istream& operator>>(istream& is, string& val);
+  istream& getline(istream& is, string& str);
+}
+
+void testCin() {
+  int x, y;
+  std::cin >> x >> y;
+  Buffer[y] = 1; // expected-warning {{Out of bound memory access }}
+}
+
+void testWcin() {
+  int x, y;
+  std::wcin >> x >> y;
+  Buffer[y] = 1; // expected-warning {{Out of bound memory access }}
+}
+
+void mySink(const std::string&, int, const char*);
+
+void testFstream() {
+  std::string str;
+  std::ifstream file("example.txt");
+  file >> str;
+  mySink(str, 0, ""); // expected-warning {{Untrusted data is passed to a user-defined sink}}
+}
+
+void testIfstream() {
+  std::string str;
+  std::fstream file("example.txt");
+  file >> str;
+  mySink(str, 0, ""); // expected-warning {{Untrusted data is passed to a user-defined sink}}
+}
+
+void testStdstring() {
+  std::string str1;
+  std::cin >> str1;
+
+  std::string& str2 = str1;
+  mySink(str2, 0, ""); // expected-warning {{Untrusted data is passed to a user-defined sink}}
+
+  const std::string& str3 = str1;
+  mySink(str3, 0, ""); // expected-warning {{Untrusted data is passed to a user-defined sink}}
+}
+
+void testTaintedThis() {
+  std::string str;
+  mySink(std::string(), 0, str.c_str()); // no-warning
+
+  std::cin >> str;
+  mySink(std::string(), 0, str.c_str()); // expected-warning {{Untrusted data is passed to a user-defined sink}}
+}
+
+void testOverloadedAssignmentOp() {
+  std::string str1, str2;
+  std::cin >> str1;
+  str2 = str1;
+  mySink(str2, 0, ""); // expected-warning {{Untrusted data is passed to a user-defined sink}}
+}
+
+void testGetline() {
+  std::string str;
+  std::getline(std::cin, str);
+  mySink(str, 0, ""); // expected-warning {{Untrusted data is passed to a user-defined sink}}
+}
Index: clang/lib/StaticAnalyzer/Checkers/Taint.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/Taint.cpp
+++ clang/lib/StaticAnalyzer/Checkers/Taint.cpp
@@ -152,6 +152,14 @@
 return isTainted(State, Sym, Kind);
   if (const MemRegion *Reg = V.getAsRegion())
 return isTainted(State, Reg, Kind);
+  if (auto LCV = V.getAs()) {
+if (Optional binding =
+State->getStateManager().getStoreManager().getDefaultBinding(
+*LCV)) {
+  if (SymbolRef Sym = binding->getAsSymbol())
+return isTainted(State, Sym, Kind);
+}
+  }
   return false;
 }
 
Index: clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
===
--- clang/lib/StaticAnalyzer/Checkers/GenericTaintChecker.cpp
+++ clang/lib/StaticAnaly

[clang-tools-extra] bbc9f6c - [clang-tidy] Add cert-oop58-cpp check

2019-12-15 Thread Gabor Bencze via cfe-commits

Author: Gabor Bencze
Date: 2019-12-15T16:30:14+01:00
New Revision: bbc9f6c2ef074668374e06a5de471413afd2ee4b

URL: 
https://github.com/llvm/llvm-project/commit/bbc9f6c2ef074668374e06a5de471413afd2ee4b
DIFF: 
https://github.com/llvm/llvm-project/commit/bbc9f6c2ef074668374e06a5de471413afd2ee4b.diff

LOG: [clang-tidy] Add cert-oop58-cpp check
The check warns when (a member of) the copied object is assigned to in a
copy constructor or copy assignment operator. Based on
https://wiki.sei.cmu.edu/confluence/display/cplusplus/OOP58-CPP.+Copy+operations+must+not+mutate+the+source+object

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

Added: 
clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp
clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.h
clang-tools-extra/docs/clang-tidy/checks/cert-oop58-cpp.rst
clang-tools-extra/test/clang-tidy/checkers/cert-oop58-cpp.cpp

Modified: 
clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
clang-tools-extra/clang-tidy/cert/CMakeLists.txt
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/list.rst

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp 
b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
index 3130dad68ffd..26f0bdab5345 100644
--- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
@@ -23,6 +23,7 @@
 #include "DontModifyStdNamespaceCheck.h"
 #include "FloatLoopCounter.h"
 #include "LimitedRandomnessCheck.h"
+#include "MutatingCopyCheck.h"
 #include "PostfixOperatorCheck.h"
 #include "ProperlySeededRandomGeneratorCheck.h"
 #include "SetLongJmpCheck.h"
@@ -69,6 +70,8 @@ class CERTModule : public ClangTidyModule {
 "cert-oop11-cpp");
 CheckFactories.registerCheck(
 "cert-oop54-cpp");
+CheckFactories.registerCheck(
+"cert-oop58-cpp");
 
 // C checkers
 // DCL

diff  --git a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt 
b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt
index 0363db7cf02d..66ea2a13acdd 100644
--- a/clang-tools-extra/clang-tidy/cert/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/cert/CMakeLists.txt
@@ -7,6 +7,7 @@ add_clang_library(clangTidyCERTModule
   DontModifyStdNamespaceCheck.cpp
   FloatLoopCounter.cpp
   LimitedRandomnessCheck.cpp
+  MutatingCopyCheck.cpp
   PostfixOperatorCheck.cpp
   ProperlySeededRandomGeneratorCheck.cpp
   SetLongJmpCheck.cpp

diff  --git a/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp 
b/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp
new file mode 100644
index ..a20a890afc70
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp
@@ -0,0 +1,83 @@
+//===--- MutatingCopyCheck.cpp - clang-tidy 
---===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===--===//
+
+#include "MutatingCopyCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace cert {
+
+static constexpr llvm::StringLiteral SourceDeclName = "ChangedPVD";
+static constexpr llvm::StringLiteral MutatingOperatorName = "MutatingOp";
+static constexpr llvm::StringLiteral MutatingCallName = "MutatingCall";
+
+void MutatingCopyCheck::registerMatchers(MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+return;
+
+  const auto MemberExprOrSourceObject = anyOf(
+  memberExpr(), declRefExpr(to(decl(equalsBoundNode(SourceDeclName);
+
+  const auto IsPartOfSource =
+  allOf(unless(hasDescendant(expr(unless(MemberExprOrSourceObject,
+MemberExprOrSourceObject);
+
+  const auto IsSourceMutatingAssignment =
+  expr(anyOf(binaryOperator(isAssignmentOperator(), hasLHS(IsPartOfSource))
+ .bind(MutatingOperatorName),
+ cxxOperatorCallExpr(isAssignmentOperator(),
+ hasArgument(0, IsPartOfSource))
+ .bind(MutatingOperatorName)));
+
+  const auto MemberExprOrSelf = anyOf(memberExpr(), cxxThisExpr());
+
+  const auto IsPartOfSelf = allOf(
+  unless(hasDescendant(expr(unless(MemberExprOrSelf, MemberExprOrSelf);
+
+  const auto IsSelfMutatingAssignment =
+  expr(anyOf(binaryOperator(isAssignmentOperator(), hasLHS(IsPartOfSelf)),
+ cxxOperatorCallExpr(isAssignmentOperator(),
+ hasArgument(0, IsPartOfSelf;
+
+  const auto IsSelfMutatingMemberFunction =
+  functionDecl(hasBody(hasDescendant(IsSelfMutatingAssignment)));
+
+  const auto IsSourceMutatingMemberCall =
+  

[PATCH] D70052: [clang-tidy] Add misc-mutating-copy check

2019-12-15 Thread Gabor Bencze via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGbbc9f6c2ef07: [clang-tidy] Add cert-oop58-cpp check The 
check warns when (a member of) the… (authored by gbencze).

Changed prior to commit:
  https://reviews.llvm.org/D70052?vs=229925&id=233966#toc

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D70052

Files:
  clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp
  clang-tools-extra/clang-tidy/cert/CMakeLists.txt
  clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.cpp
  clang-tools-extra/clang-tidy/cert/MutatingCopyCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/cert-oop58-cpp.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/cert-oop58-cpp.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/cert-oop58-cpp.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/cert-oop58-cpp.cpp
@@ -0,0 +1,149 @@
+// RUN: %check_clang_tidy %s cert-oop58-cpp %t
+
+// Example test cases from CERT rule
+// https://wiki.sei.cmu.edu/confluence/display/cplusplus/OOP58-CPP.+Copy+operations+must+not+mutate+the+source+object
+namespace test_mutating_noncompliant_example {
+class A {
+  mutable int m;
+
+public:
+  A() : m(0) {}
+  explicit A(int m) : m(m) {}
+
+  A(const A &other) : m(other.m) {
+other.m = 0;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: mutating copied object
+  }
+
+  A &operator=(const A &other) {
+if (&other != this) {
+  m = other.m;
+  other.m = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: mutating copied object
+}
+return *this;
+  }
+
+  int get_m() const { return m; }
+};
+} // namespace test_mutating_noncompliant_example
+
+namespace test_mutating_compliant_example {
+class B {
+  int m;
+
+public:
+  B() : m(0) {}
+  explicit B(int m) : m(m) {}
+
+  B(const B &other) : m(other.m) {}
+  B(B &&other) : m(other.m) {
+other.m = 0; //no-warning: mutation allowed in move constructor
+  }
+
+  B &operator=(const B &other) {
+if (&other != this) {
+  m = other.m;
+}
+return *this;
+  }
+
+  B &operator=(B &&other) {
+m = other.m;
+other.m = 0; //no-warning: mutation allowed in move assignment operator
+return *this;
+  }
+
+  int get_m() const { return m; }
+};
+} // namespace test_mutating_compliant_example
+
+namespace test_mutating_pointer {
+class C {
+  C *ptr;
+  int value;
+
+  C();
+  C(C &other) {
+other = {};
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: mutating copied object
+other.ptr = nullptr;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: mutating copied object
+other.value = 0;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: mutating copied object
+
+// no-warning: mutating a pointee is allowed
+other.ptr->value = 0;
+*other.ptr = {};
+  }
+};
+} // namespace test_mutating_pointer
+
+namespace test_mutating_indirect_member {
+struct S {
+  int x;
+};
+
+class D {
+  S s;
+  D(D &other) {
+other.s = {};
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: mutating copied object
+other.s.x = 0;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: mutating copied object
+  }
+};
+} // namespace test_mutating_indirect_member
+
+namespace test_mutating_other_object {
+class E {
+  E();
+  E(E &other) {
+E tmp;
+// no-warning: mutating an object that is not the source is allowed
+tmp = {};
+  }
+};
+} // namespace test_mutating_other_object
+
+namespace test_mutating_member_function {
+class F {
+  int a;
+
+public:
+  void bad_func() { a = 12; }
+  void fine_func() const;
+  void fine_func_2(int x) { x = 5; }
+  void questionable_func();
+
+  F(F &other) : a(other.a) {
+this->bad_func(); // no-warning: mutating this is allowed
+
+other.bad_func();
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: call mutates copied object
+
+other.fine_func();
+other.fine_func_2(42);
+other.questionable_func();
+  }
+};
+} // namespace test_mutating_member_function
+
+namespace test_mutating_function_on_nested_object {
+struct S {
+  int x;
+  void mutate(int y) {
+x = y;
+  }
+};
+
+class G {
+  S s;
+  G(G &other) {
+s.mutate(0); // no-warning: mutating this is allowed
+
+other.s.mutate(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: call mutates copied object
+  }
+};
+} // namespace test_mutating_function_on_nested_object
Index: clang-tools-extra/docs/clang-tidy/checks/list.rst
===
--- clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -107,6 +107,7 @@
cert-msc51-cpp
cert-oop11-cpp (redirects to performance-move-constructor-init) 
cert-oop54-cpp (redirects to bugprone-unhandled-self-assignment) 
+   cert-oop58-cpp
cert-pos44-c (redire

[PATCH] D69223: WDocumentation: Implement the \anchor.

2019-12-15 Thread Mark de Wever via Phabricator via cfe-commits
Mordante marked an inline comment as done.
Mordante added inline comments.



Comment at: clang/lib/AST/TextNodeDumper.cpp:493
+  case comments::InlineCommandComment::RenderAnchor:
+OS << " RenderAnchor";
+break;

Mordante wrote:
> gribozavr2 wrote:
> > Please add a test for this one to 
> > clang/test/Index/comment-to-html-xml-conversion.cpp (search for 
> > RenderEmphasized in that file).
> I already added a test to 
> `clang/test/Index/comment-to-html-xml-conversion.cpp`. I forgot to add a test 
> to `clang/test/AST/ast-dump-comment.cpp`, is this the file you meant?
@gribozavr2 In case you missed the question above, could you have a look at the 
question?


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

https://reviews.llvm.org/D69223



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


[PATCH] D71397: [clang] Improve LLVM-style RTTI support in ExternalASTSource/ExternalSemaSource

2019-12-15 Thread Raphael Isemann via Phabricator via cfe-commits
teemperor updated this revision to Diff 233968.
teemperor added a comment.

- Addressed Adrian's comments.


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

https://reviews.llvm.org/D71397

Files:
  clang/include/clang/AST/ExternalASTSource.h
  clang/include/clang/Sema/ExternalSemaSource.h
  clang/include/clang/Sema/MultiplexExternalSemaSource.h
  clang/lib/AST/ExternalASTSource.cpp
  clang/lib/Sema/MultiplexExternalSemaSource.cpp
  clang/lib/Sema/Sema.cpp

Index: clang/lib/Sema/Sema.cpp
===
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -1917,6 +1917,7 @@
 
 // Pin this vtable to this file.
 ExternalSemaSource::~ExternalSemaSource() {}
+char ExternalSemaSource::ID;
 
 void ExternalSemaSource::ReadMethodPool(Selector Sel) { }
 void ExternalSemaSource::updateOutOfDateSelector(Selector Sel) { }
Index: clang/lib/Sema/MultiplexExternalSemaSource.cpp
===
--- clang/lib/Sema/MultiplexExternalSemaSource.cpp
+++ clang/lib/Sema/MultiplexExternalSemaSource.cpp
@@ -15,6 +15,8 @@
 
 using namespace clang;
 
+char MultiplexExternalSemaSource::ID;
+
 ///Constructs a new multiplexing external sema source and appends the
 /// given element to it.
 ///
Index: clang/lib/AST/ExternalASTSource.cpp
===
--- clang/lib/AST/ExternalASTSource.cpp
+++ clang/lib/AST/ExternalASTSource.cpp
@@ -24,6 +24,8 @@
 
 using namespace clang;
 
+char ExternalASTSource::ID;
+
 ExternalASTSource::~ExternalASTSource() = default;
 
 llvm::Optional
Index: clang/include/clang/Sema/MultiplexExternalSemaSource.h
===
--- clang/include/clang/Sema/MultiplexExternalSemaSource.h
+++ clang/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -36,6 +36,8 @@
 /// external AST sources that also provide information for semantic
 /// analysis.
 class MultiplexExternalSemaSource : public ExternalSemaSource {
+  /// LLVM-style RTTI.
+  static char ID;
 
 private:
   SmallVector Sources; // doesn't own them.
@@ -352,9 +354,13 @@
   bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
 QualType T) override;
 
-  // isa/cast/dyn_cast support
-  static bool classof(const MultiplexExternalSemaSource*) { return true; }
-  //static bool classof(const ExternalSemaSource*) { return true; }
+  /// LLVM-style RTTI.
+  /// \{
+  bool isA(const void *ClassID) const override {
+return ClassID == &ID || ExternalSemaSource::isA(ClassID);
+  }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
 };
 
 } // end namespace clang
Index: clang/include/clang/Sema/ExternalSemaSource.h
===
--- clang/include/clang/Sema/ExternalSemaSource.h
+++ clang/include/clang/Sema/ExternalSemaSource.h
@@ -50,10 +50,11 @@
 /// external AST sources that also provide information for semantic
 /// analysis.
 class ExternalSemaSource : public ExternalASTSource {
+  /// LLVM-style RTTI.
+  static char ID;
+
 public:
-  ExternalSemaSource() {
-ExternalASTSource::SemaSource = true;
-  }
+  ExternalSemaSource() = default;
 
   ~ExternalSemaSource() override;
 
@@ -222,10 +223,13 @@
 return false;
   }
 
-  // isa/cast/dyn_cast support
-  static bool classof(const ExternalASTSource *Source) {
-return Source->SemaSource;
+  /// LLVM-style RTTI.
+  /// \{
+  bool isA(const void *ClassID) const override {
+return ClassID == &ID || ExternalASTSource::isA(ClassID);
   }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
 };
 
 } // end namespace clang
Index: clang/include/clang/AST/ExternalASTSource.h
===
--- clang/include/clang/AST/ExternalASTSource.h
+++ clang/include/clang/AST/ExternalASTSource.h
@@ -66,9 +66,8 @@
   /// whenever we might have added new redeclarations for existing decls.
   uint32_t CurrentGeneration = 0;
 
-  /// Whether this AST source also provides information for
-  /// semantic analysis.
-  bool SemaSource = false;
+  /// LLVM-style RTTI.
+  static char ID;
 
 public:
   ExternalASTSource() = default;
@@ -325,6 +324,12 @@
 
   virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
 
+  /// LLVM-style RTTI.
+  /// \{
+  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
+
 protected:
   static DeclContextLookupResult
   SetExternalVisibleDeclsForName(const DeclContext *DC,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] aa45584 - [clang] Improve LLVM-style RTTI support in ExternalASTSource/ExternalSemaSource

2019-12-15 Thread Raphael Isemann via cfe-commits

Author: Raphael Isemann
Date: 2019-12-15T18:11:01+01:00
New Revision: aa4558497ff6301881adf38960dd2f4d95aa8fc5

URL: 
https://github.com/llvm/llvm-project/commit/aa4558497ff6301881adf38960dd2f4d95aa8fc5
DIFF: 
https://github.com/llvm/llvm-project/commit/aa4558497ff6301881adf38960dd2f4d95aa8fc5.diff

LOG: [clang] Improve LLVM-style RTTI support in 
ExternalASTSource/ExternalSemaSource

Summary:
We currently have some very basic LLVM-style RTTI support in the 
ExternalASTSource class hierarchy
based on the `SemaSource` bool( to discriminate it form the 
ExternalSemaSource). As ExternalASTSource
is supposed to be subclassed we should have extendable LLVM-style RTTI in this 
class hierarchy to make life easier
for projects building on top of Clang.

Most notably the current RTTI implementation forces LLDB to implement RTTI for 
its
own ExternalASTSource class (ClangExternalASTSourceCommon) by keeping a global 
set of
ExternalASTSources that are known to be ClangExternalASTSourceCommon. Projects
using Clang currently have to dosimilar workarounds to get RTTI support for 
their subclasses.

This patch turns this into full-fledged LLVM-style RTTI based on a static `ID` 
variable similar to
other LLVM class hierarchies. Also removes the friend declaration from 
ExternalASTSource to
its child class that was only used to grant access to the `SemaSource` member.

Reviewers: aprantl, dblaikie, rjmccall

Reviewed By: aprantl

Subscribers: riccibruno, labath, lhames, cfe-commits

Tags: #clang

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

Added: 


Modified: 
clang/include/clang/AST/ExternalASTSource.h
clang/include/clang/Sema/ExternalSemaSource.h
clang/include/clang/Sema/MultiplexExternalSemaSource.h
clang/lib/AST/ExternalASTSource.cpp
clang/lib/Sema/MultiplexExternalSemaSource.cpp
clang/lib/Sema/Sema.cpp

Removed: 




diff  --git a/clang/include/clang/AST/ExternalASTSource.h 
b/clang/include/clang/AST/ExternalASTSource.h
index 304633668bd1..899ac3f66937 100644
--- a/clang/include/clang/AST/ExternalASTSource.h
+++ b/clang/include/clang/AST/ExternalASTSource.h
@@ -66,9 +66,8 @@ class ExternalASTSource : public 
RefCountedBase {
   /// whenever we might have added new redeclarations for existing decls.
   uint32_t CurrentGeneration = 0;
 
-  /// Whether this AST source also provides information for
-  /// semantic analysis.
-  bool SemaSource = false;
+  /// LLVM-style RTTI.
+  static char ID;
 
 public:
   ExternalASTSource() = default;
@@ -325,6 +324,12 @@ class ExternalASTSource : public 
RefCountedBase {
 
   virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
 
+  /// LLVM-style RTTI.
+  /// \{
+  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
+
 protected:
   static DeclContextLookupResult
   SetExternalVisibleDeclsForName(const DeclContext *DC,

diff  --git a/clang/include/clang/Sema/ExternalSemaSource.h 
b/clang/include/clang/Sema/ExternalSemaSource.h
index 88fa6f53d8bf..c79ca0e71df5 100644
--- a/clang/include/clang/Sema/ExternalSemaSource.h
+++ b/clang/include/clang/Sema/ExternalSemaSource.h
@@ -50,10 +50,11 @@ struct ExternalVTableUse {
 /// external AST sources that also provide information for semantic
 /// analysis.
 class ExternalSemaSource : public ExternalASTSource {
+  /// LLVM-style RTTI.
+  static char ID;
+
 public:
-  ExternalSemaSource() {
-ExternalASTSource::SemaSource = true;
-  }
+  ExternalSemaSource() = default;
 
   ~ExternalSemaSource() override;
 
@@ -222,10 +223,13 @@ class ExternalSemaSource : public ExternalASTSource {
 return false;
   }
 
-  // isa/cast/dyn_cast support
-  static bool classof(const ExternalASTSource *Source) {
-return Source->SemaSource;
+  /// LLVM-style RTTI.
+  /// \{
+  bool isA(const void *ClassID) const override {
+return ClassID == &ID || ExternalASTSource::isA(ClassID);
   }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
 };
 
 } // end namespace clang

diff  --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h 
b/clang/include/clang/Sema/MultiplexExternalSemaSource.h
index 8157e488d3b1..dcbac9f0ba10 100644
--- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h
+++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -36,6 +36,8 @@ namespace clang {
 /// external AST sources that also provide information for semantic
 /// analysis.
 class MultiplexExternalSemaSource : public ExternalSemaSource {
+  /// LLVM-style RTTI.
+  static char ID;
 
 private:
   SmallVector Sources; // doesn't own them.
@@ -352,9 +354,13 @@ class MultiplexExternalSemaSource : public 
ExternalSemaSource {
   bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
 QualType T) override;
 
-  // isa/cast/dyn_cast support
-  static 

[PATCH] D71397: [clang] Improve LLVM-style RTTI support in ExternalASTSource/ExternalSemaSource

2019-12-15 Thread Raphael Isemann via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGaa4558497ff6: [clang] Improve LLVM-style RTTI support in 
ExternalASTSource/ExternalSemaSource (authored by teemperor).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71397

Files:
  clang/include/clang/AST/ExternalASTSource.h
  clang/include/clang/Sema/ExternalSemaSource.h
  clang/include/clang/Sema/MultiplexExternalSemaSource.h
  clang/lib/AST/ExternalASTSource.cpp
  clang/lib/Sema/MultiplexExternalSemaSource.cpp
  clang/lib/Sema/Sema.cpp

Index: clang/lib/Sema/Sema.cpp
===
--- clang/lib/Sema/Sema.cpp
+++ clang/lib/Sema/Sema.cpp
@@ -1917,6 +1917,7 @@
 
 // Pin this vtable to this file.
 ExternalSemaSource::~ExternalSemaSource() {}
+char ExternalSemaSource::ID;
 
 void ExternalSemaSource::ReadMethodPool(Selector Sel) { }
 void ExternalSemaSource::updateOutOfDateSelector(Selector Sel) { }
Index: clang/lib/Sema/MultiplexExternalSemaSource.cpp
===
--- clang/lib/Sema/MultiplexExternalSemaSource.cpp
+++ clang/lib/Sema/MultiplexExternalSemaSource.cpp
@@ -15,6 +15,8 @@
 
 using namespace clang;
 
+char MultiplexExternalSemaSource::ID;
+
 ///Constructs a new multiplexing external sema source and appends the
 /// given element to it.
 ///
Index: clang/lib/AST/ExternalASTSource.cpp
===
--- clang/lib/AST/ExternalASTSource.cpp
+++ clang/lib/AST/ExternalASTSource.cpp
@@ -24,6 +24,8 @@
 
 using namespace clang;
 
+char ExternalASTSource::ID;
+
 ExternalASTSource::~ExternalASTSource() = default;
 
 llvm::Optional
Index: clang/include/clang/Sema/MultiplexExternalSemaSource.h
===
--- clang/include/clang/Sema/MultiplexExternalSemaSource.h
+++ clang/include/clang/Sema/MultiplexExternalSemaSource.h
@@ -36,6 +36,8 @@
 /// external AST sources that also provide information for semantic
 /// analysis.
 class MultiplexExternalSemaSource : public ExternalSemaSource {
+  /// LLVM-style RTTI.
+  static char ID;
 
 private:
   SmallVector Sources; // doesn't own them.
@@ -352,9 +354,13 @@
   bool MaybeDiagnoseMissingCompleteType(SourceLocation Loc,
 QualType T) override;
 
-  // isa/cast/dyn_cast support
-  static bool classof(const MultiplexExternalSemaSource*) { return true; }
-  //static bool classof(const ExternalSemaSource*) { return true; }
+  /// LLVM-style RTTI.
+  /// \{
+  bool isA(const void *ClassID) const override {
+return ClassID == &ID || ExternalSemaSource::isA(ClassID);
+  }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
 };
 
 } // end namespace clang
Index: clang/include/clang/Sema/ExternalSemaSource.h
===
--- clang/include/clang/Sema/ExternalSemaSource.h
+++ clang/include/clang/Sema/ExternalSemaSource.h
@@ -50,10 +50,11 @@
 /// external AST sources that also provide information for semantic
 /// analysis.
 class ExternalSemaSource : public ExternalASTSource {
+  /// LLVM-style RTTI.
+  static char ID;
+
 public:
-  ExternalSemaSource() {
-ExternalASTSource::SemaSource = true;
-  }
+  ExternalSemaSource() = default;
 
   ~ExternalSemaSource() override;
 
@@ -222,10 +223,13 @@
 return false;
   }
 
-  // isa/cast/dyn_cast support
-  static bool classof(const ExternalASTSource *Source) {
-return Source->SemaSource;
+  /// LLVM-style RTTI.
+  /// \{
+  bool isA(const void *ClassID) const override {
+return ClassID == &ID || ExternalASTSource::isA(ClassID);
   }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
 };
 
 } // end namespace clang
Index: clang/include/clang/AST/ExternalASTSource.h
===
--- clang/include/clang/AST/ExternalASTSource.h
+++ clang/include/clang/AST/ExternalASTSource.h
@@ -66,9 +66,8 @@
   /// whenever we might have added new redeclarations for existing decls.
   uint32_t CurrentGeneration = 0;
 
-  /// Whether this AST source also provides information for
-  /// semantic analysis.
-  bool SemaSource = false;
+  /// LLVM-style RTTI.
+  static char ID;
 
 public:
   ExternalASTSource() = default;
@@ -325,6 +324,12 @@
 
   virtual void getMemoryBufferSizes(MemoryBufferSizes &sizes) const;
 
+  /// LLVM-style RTTI.
+  /// \{
+  virtual bool isA(const void *ClassID) const { return ClassID == &ID; }
+  static bool classof(const ExternalASTSource *S) { return S->isA(&ID); }
+  /// \}
+
 protected:
   static DeclContextLookupResult
   SetExternalVisibleDeclsForName(const DeclContext *DC,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mail

[PATCH] D71526: [AST] Use a reference in a range-based for

2019-12-15 Thread Mark de Wever via Phabricator via cfe-commits
Mordante created this revision.
Mordante added reviewers: rsmith, aaron.ballman, xbolva00.
Mordante added a project: clang.

This avoids unneeded copies when using a range-based for loops.

This avoids new warnings due to D68912  adds 
-Wrange-loop-analysis to -Wall.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71526

Files:
  clang/lib/AST/ASTContext.cpp


Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2462,7 +2462,7 @@
   return llvm::None;
 
 SmallVector, 4> Bases;
-for (const auto Base : ClassDecl->bases()) {
+for (const auto &Base : ClassDecl->bases()) {
   // Empty types can be inherited from, and non-empty types can potentially
   // have tail padding, so just make sure there isn't an error.
   if (!isStructEmpty(Base.getType())) {
@@ -2480,7 +2480,7 @@
  Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl());
 });
 
-for (const auto Base : Bases) {
+for (const auto &Base : Bases) {
   int64_t BaseOffset = Context.toBits(
   Layout.getBaseClassOffset(Base.first->getAsCXXRecordDecl()));
   int64_t BaseSize = Base.second;


Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2462,7 +2462,7 @@
   return llvm::None;
 
 SmallVector, 4> Bases;
-for (const auto Base : ClassDecl->bases()) {
+for (const auto &Base : ClassDecl->bases()) {
   // Empty types can be inherited from, and non-empty types can potentially
   // have tail padding, so just make sure there isn't an error.
   if (!isStructEmpty(Base.getType())) {
@@ -2480,7 +2480,7 @@
  Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl());
 });
 
-for (const auto Base : Bases) {
+for (const auto &Base : Bases) {
   int64_t BaseOffset = Context.toBits(
   Layout.getBaseClassOffset(Base.first->getAsCXXRecordDecl()));
   int64_t BaseSize = Base.second;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D71527: [Driver] Avoid copies in range-based for loops

2019-12-15 Thread Mark de Wever via Phabricator via cfe-commits
Mordante created this revision.
Mordante added reviewers: Eugene.Zelenko, sepavloff, aaron.ballman, xbolva00.
Mordante added a project: clang.

This avoids new warnings due to D68912  adds 
-Wrange-loop-analysis to -Wall.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71527

Files:
  clang/lib/Driver/Driver.cpp
  clang/lib/Driver/ToolChain.cpp


Index: clang/lib/Driver/ToolChain.cpp
===
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -850,7 +850,7 @@
 /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
  ArgStringList &CC1Args,
  ArrayRef Paths) {
-  for (const auto Path : Paths) {
+  for (const auto &Path : Paths) {
 CC1Args.push_back("-internal-isystem");
 CC1Args.push_back(DriverArgs.MakeArgString(Path));
   }
Index: clang/lib/Driver/Driver.cpp
===
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -744,7 +744,7 @@
   ArrayRef Dirs,
   StringRef FileName) {
   SmallString<128> WPath;
-  for (const StringRef &Dir : Dirs) {
+  for (const std::string &Dir : Dirs) {
 if (Dir.empty())
   continue;
 WPath.clear();


Index: clang/lib/Driver/ToolChain.cpp
===
--- clang/lib/Driver/ToolChain.cpp
+++ clang/lib/Driver/ToolChain.cpp
@@ -850,7 +850,7 @@
 /*static*/ void ToolChain::addSystemIncludes(const ArgList &DriverArgs,
  ArgStringList &CC1Args,
  ArrayRef Paths) {
-  for (const auto Path : Paths) {
+  for (const auto &Path : Paths) {
 CC1Args.push_back("-internal-isystem");
 CC1Args.push_back(DriverArgs.MakeArgString(Path));
   }
Index: clang/lib/Driver/Driver.cpp
===
--- clang/lib/Driver/Driver.cpp
+++ clang/lib/Driver/Driver.cpp
@@ -744,7 +744,7 @@
   ArrayRef Dirs,
   StringRef FileName) {
   SmallString<128> WPath;
-  for (const StringRef &Dir : Dirs) {
+  for (const std::string &Dir : Dirs) {
 if (Dir.empty())
   continue;
 WPath.clear();
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D71529: [Sema] Fixes -Wrange-loop-analysis warnings

2019-12-15 Thread Mark de Wever via Phabricator via cfe-commits
Mordante created this revision.
Mordante added reviewers: rsmith, aaron.ballman, xbolva00.
Mordante added a project: clang.

This avoids new warnings due to D68912  adds 
-Wrange-loop-analysis to -Wall.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71529

Files:
  clang/lib/Sema/AnalysisBasedWarnings.cpp
  clang/lib/Sema/SemaCodeComplete.cpp


Index: clang/lib/Sema/SemaCodeComplete.cpp
===
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ clang/lib/Sema/SemaCodeComplete.cpp
@@ -1309,7 +1309,7 @@
 /// Motivating case is const_iterator begin() const vs iterator 
begin().
 auto &OverloadSet = OverloadMap[std::make_pair(
 CurContext, Method->getDeclName().getAsOpaqueInteger())];
-for (const DeclIndexPair& Entry : OverloadSet) {
+for (const DeclIndexPair Entry : OverloadSet) {
   Result &Incumbent = Results[Entry.second];
   switch (compareOverloads(*Method,
*cast(Incumbent.Declaration),
Index: clang/lib/Sema/AnalysisBasedWarnings.cpp
===
--- clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1174,7 +1174,7 @@
 // We analyze lambda bodies separately. Skip them here.
 bool TraverseLambdaExpr(LambdaExpr *LE) {
   // Traverse the captures, but not the body.
-  for (const auto &C : zip(LE->captures(), LE->capture_inits()))
+  for (const auto C : zip(LE->captures(), LE->capture_inits()))
 TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
   return true;
 }


Index: clang/lib/Sema/SemaCodeComplete.cpp
===
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ clang/lib/Sema/SemaCodeComplete.cpp
@@ -1309,7 +1309,7 @@
 /// Motivating case is const_iterator begin() const vs iterator begin().
 auto &OverloadSet = OverloadMap[std::make_pair(
 CurContext, Method->getDeclName().getAsOpaqueInteger())];
-for (const DeclIndexPair& Entry : OverloadSet) {
+for (const DeclIndexPair Entry : OverloadSet) {
   Result &Incumbent = Results[Entry.second];
   switch (compareOverloads(*Method,
*cast(Incumbent.Declaration),
Index: clang/lib/Sema/AnalysisBasedWarnings.cpp
===
--- clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -1174,7 +1174,7 @@
 // We analyze lambda bodies separately. Skip them here.
 bool TraverseLambdaExpr(LambdaExpr *LE) {
   // Traverse the captures, but not the body.
-  for (const auto &C : zip(LE->captures(), LE->capture_inits()))
+  for (const auto C : zip(LE->captures(), LE->capture_inits()))
 TraverseLambdaCapture(LE, &std::get<0>(C), std::get<1>(C));
   return true;
 }
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D71530: [Frontend] Fixes -Wrange-loop-analysis warnings

2019-12-15 Thread Mark de Wever via Phabricator via cfe-commits
Mordante created this revision.
Mordante added reviewers: rsmith, aaron.ballman, xbolva00.
Mordante added a project: clang.

This avoids new warnings due to D68912  adds 
-Wrange-loop-analysis to -Wall.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71530

Files:
  clang/lib/Frontend/CompilerInvocation.cpp


Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -334,7 +334,7 @@
 StringRef CheckerAndPackageList = A->getValue();
 SmallVector CheckersAndPackages;
 CheckerAndPackageList.split(CheckersAndPackages, ",");
-for (const StringRef CheckerOrPackage : CheckersAndPackages)
+for (const StringRef &CheckerOrPackage : CheckersAndPackages)
   Opts.CheckersAndPackages.emplace_back(CheckerOrPackage, IsEnabled);
   }
 
@@ -476,7 +476,7 @@
 SmallVector CheckersAndPackages;
 AnOpts.RawSilencedCheckersAndPackages.split(CheckersAndPackages, ";");
 
-for (const StringRef CheckerOrPackage : CheckersAndPackages) {
+for (const StringRef &CheckerOrPackage : CheckersAndPackages) {
   if (Diags) {
 bool IsChecker = CheckerOrPackage.contains('.');
 bool IsValidName =
@@ -607,7 +607,7 @@
XRayInstrSet &S) {
   llvm::SmallVector BundleParts;
   llvm::SplitString(Bundle, BundleParts, ",");
-  for (const auto B : BundleParts) {
+  for (const auto &B : BundleParts) {
 auto Mask = parseXRayInstrValue(B);
 if (Mask == XRayInstrKind::None)
   if (B != "none")


Index: clang/lib/Frontend/CompilerInvocation.cpp
===
--- clang/lib/Frontend/CompilerInvocation.cpp
+++ clang/lib/Frontend/CompilerInvocation.cpp
@@ -334,7 +334,7 @@
 StringRef CheckerAndPackageList = A->getValue();
 SmallVector CheckersAndPackages;
 CheckerAndPackageList.split(CheckersAndPackages, ",");
-for (const StringRef CheckerOrPackage : CheckersAndPackages)
+for (const StringRef &CheckerOrPackage : CheckersAndPackages)
   Opts.CheckersAndPackages.emplace_back(CheckerOrPackage, IsEnabled);
   }
 
@@ -476,7 +476,7 @@
 SmallVector CheckersAndPackages;
 AnOpts.RawSilencedCheckersAndPackages.split(CheckersAndPackages, ";");
 
-for (const StringRef CheckerOrPackage : CheckersAndPackages) {
+for (const StringRef &CheckerOrPackage : CheckersAndPackages) {
   if (Diags) {
 bool IsChecker = CheckerOrPackage.contains('.');
 bool IsValidName =
@@ -607,7 +607,7 @@
XRayInstrSet &S) {
   llvm::SmallVector BundleParts;
   llvm::SplitString(Bundle, BundleParts, ",");
-  for (const auto B : BundleParts) {
+  for (const auto &B : BundleParts) {
 auto Mask = parseXRayInstrValue(B);
 if (Mask == XRayInstrKind::None)
   if (B != "none")
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 29e78ec - [AST] Use a reference in a range-based for

2019-12-15 Thread Mark de Wever via cfe-commits

Author: Mark de Wever
Date: 2019-12-15T21:17:07+01:00
New Revision: 29e78ec67988a5aa712da805f8197bfa3d738700

URL: 
https://github.com/llvm/llvm-project/commit/29e78ec67988a5aa712da805f8197bfa3d738700
DIFF: 
https://github.com/llvm/llvm-project/commit/29e78ec67988a5aa712da805f8197bfa3d738700.diff

LOG: [AST] Use a reference in a range-based for

This avoids unneeded copies when using a range-based for loops.

This avoids new warnings due to D68912 adds -Wrange-loop-analysis to -Wall.

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

Added: 


Modified: 
clang/lib/AST/ASTContext.cpp

Removed: 




diff  --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 4fd7e20dac84..1046663c7009 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2462,7 +2462,7 @@ structHasUniqueObjectRepresentations(const ASTContext 
&Context,
   return llvm::None;
 
 SmallVector, 4> Bases;
-for (const auto Base : ClassDecl->bases()) {
+for (const auto &Base : ClassDecl->bases()) {
   // Empty types can be inherited from, and non-empty types can potentially
   // have tail padding, so just make sure there isn't an error.
   if (!isStructEmpty(Base.getType())) {
@@ -2480,7 +2480,7 @@ structHasUniqueObjectRepresentations(const ASTContext 
&Context,
  Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl());
 });
 
-for (const auto Base : Bases) {
+for (const auto &Base : Bases) {
   int64_t BaseOffset = Context.toBits(
   Layout.getBaseClassOffset(Base.first->getAsCXXRecordDecl()));
   int64_t BaseSize = Base.second;



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


[PATCH] D71526: [AST] Use a reference in a range-based for

2019-12-15 Thread Mark de Wever via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rG29e78ec67988: [AST] Use a reference in a range-based for 
(authored by Mordante).

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D71526

Files:
  clang/lib/AST/ASTContext.cpp


Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2462,7 +2462,7 @@
   return llvm::None;
 
 SmallVector, 4> Bases;
-for (const auto Base : ClassDecl->bases()) {
+for (const auto &Base : ClassDecl->bases()) {
   // Empty types can be inherited from, and non-empty types can potentially
   // have tail padding, so just make sure there isn't an error.
   if (!isStructEmpty(Base.getType())) {
@@ -2480,7 +2480,7 @@
  Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl());
 });
 
-for (const auto Base : Bases) {
+for (const auto &Base : Bases) {
   int64_t BaseOffset = Context.toBits(
   Layout.getBaseClassOffset(Base.first->getAsCXXRecordDecl()));
   int64_t BaseSize = Base.second;


Index: clang/lib/AST/ASTContext.cpp
===
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2462,7 +2462,7 @@
   return llvm::None;
 
 SmallVector, 4> Bases;
-for (const auto Base : ClassDecl->bases()) {
+for (const auto &Base : ClassDecl->bases()) {
   // Empty types can be inherited from, and non-empty types can potentially
   // have tail padding, so just make sure there isn't an error.
   if (!isStructEmpty(Base.getType())) {
@@ -2480,7 +2480,7 @@
  Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl());
 });
 
-for (const auto Base : Bases) {
+for (const auto &Base : Bases) {
   int64_t BaseOffset = Context.toBits(
   Layout.getBaseClassOffset(Base.first->getAsCXXRecordDecl()));
   int64_t BaseSize = Base.second;
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 0ec1e99 - Resolve exception specifications after marking the corresponding

2019-12-15 Thread Richard Smith via cfe-commits

Author: Richard Smith
Date: 2019-12-15T22:02:30-08:00
New Revision: 0ec1e99001291b894de4cd8d7ecc2a283d9a3bfc

URL: 
https://github.com/llvm/llvm-project/commit/0ec1e99001291b894de4cd8d7ecc2a283d9a3bfc
DIFF: 
https://github.com/llvm/llvm-project/commit/0ec1e99001291b894de4cd8d7ecc2a283d9a3bfc.diff

LOG: Resolve exception specifications after marking the corresponding
function as referenced, not before.

No functionality change intended. This is groundwork for computing the
exception specification of a defaulted comparison, for which we'd like
to use the implicit body where possible.

Added: 


Modified: 
clang/lib/Sema/SemaExpr.cpp
clang/lib/Sema/SemaExprMember.cpp
clang/lib/Sema/SemaOverload.cpp

Removed: 




diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index a57ee7b0ff21..e1921f0ddf78 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1827,6 +1827,25 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, 
ExprValueKind VK,
   VK, FoundD, TemplateArgs, getNonOdrUseReasonInCurrentContext(D));
   MarkDeclRefReferenced(E);
 
+  // C++ [except.spec]p17:
+  //   An exception-specification is considered to be needed when:
+  //   - in an expression, the function is the unique lookup result or
+  // the selected member of a set of overloaded functions.
+  //
+  // We delay doing this until after we've built the function reference and
+  // marked it as used so that:
+  //  a) if the function is defaulted, we get errors from defining it before /
+  // instead of errors from computing its exception specification, and
+  //  b) if the function is a defaulted comparison, we can use the body we
+  // build when defining it as input to the exception specification
+  // computation rather than computing a new body.
+  if (auto *FPT = Ty->getAs()) {
+if (isUnresolvedExceptionSpec(FPT->getExceptionSpecType())) {
+  if (auto *NewFPT = ResolveExceptionSpec(NameInfo.getLoc(), FPT))
+E->setType(Context.getQualifiedType(NewFPT, Ty.getQualifiers()));
+}
+  }
+
   if (getLangOpts().ObjCWeak && isa(D) &&
   Ty.getObjCLifetime() == Qualifiers::OCL_Weak && !isUnevaluatedContext() 
&&
   !Diags.isIgnored(diag::warn_arc_repeated_use_of_weak, E->getBeginLoc()))
@@ -3009,14 +3028,6 @@ ExprResult Sema::BuildDeclarationNameExpr(
 QualType type = VD->getType();
 if (type.isNull())
   return ExprError();
-if (auto *FPT = type->getAs()) {
-  // C++ [except.spec]p17:
-  //   An exception-specification is considered to be needed when:
-  //   - in an expression, the function is the unique lookup result or
-  // the selected member of a set of overloaded functions.
-  ResolveExceptionSpec(Loc, FPT);
-  type = VD->getType();
-}
 ExprValueKind valueKind = VK_RValue;
 
 switch (D->getKind()) {
@@ -15480,19 +15491,6 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, 
FunctionDecl *Func,
Func->getMemberSpecializationInfo()))
 checkSpecializationVisibility(Loc, Func);
 
-  // C++14 [except.spec]p17:
-  //   An exception-specification is considered to be needed when:
-  //   - the function is odr-used or, if it appears in an unevaluated operand,
-  // would be odr-used if the expression were potentially-evaluated;
-  //
-  // Note, we do this even if MightBeOdrUse is false. That indicates that the
-  // function is a pure virtual function we're calling, and in that case the
-  // function was selected by overload resolution and we need to resolve its
-  // exception specification for a 
diff erent reason.
-  const FunctionProtoType *FPT = Func->getType()->getAs();
-  if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
-ResolveExceptionSpec(Loc, FPT);
-
   if (getLangOpts().CUDA)
 CheckCUDACall(Loc, Func);
 
@@ -15601,6 +15599,19 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, 
FunctionDecl *Func,
 });
   }
 
+  // C++14 [except.spec]p17:
+  //   An exception-specification is considered to be needed when:
+  //   - the function is odr-used or, if it appears in an unevaluated operand,
+  // would be odr-used if the expression were potentially-evaluated;
+  //
+  // Note, we do this even if MightBeOdrUse is false. That indicates that the
+  // function is a pure virtual function we're calling, and in that case the
+  // function was selected by overload resolution and we need to resolve its
+  // exception specification for a 
diff erent reason.
+  const FunctionProtoType *FPT = Func->getType()->getAs();
+  if (FPT && isUnresolvedExceptionSpec(FPT->getExceptionSpecType()))
+ResolveExceptionSpec(Loc, FPT);
+
   // If this is the first "real" use, act on that.
   if (OdrUse == OdrUseContext::Used && !Func->isUsed(/*CheckUsedAttr=*/false)) 
{
 // Keep track of used but undefined functions.

diff  --git a/clang/lib/Sema/SemaExprMember

[clang] fbf60b7 - Properly compute whether statement expressions can throw, rather than

2019-12-15 Thread Richard Smith via cfe-commits

Author: Richard Smith
Date: 2019-12-15T22:02:31-08:00
New Revision: fbf60b7dbeb0f66b45037925c384859f2f161504

URL: 
https://github.com/llvm/llvm-project/commit/fbf60b7dbeb0f66b45037925c384859f2f161504
DIFF: 
https://github.com/llvm/llvm-project/commit/fbf60b7dbeb0f66b45037925c384859f2f161504.diff

LOG: Properly compute whether statement expressions can throw, rather than
conservatively assuming they always can.

Also fix cases where we would not consider the computation of a VLA type
when determining whether an expression can throw. We don't yet properly
determine whether a VLA can throw, but no longer incorrectly claim it
can never throw.

Added: 


Modified: 
clang/include/clang/AST/Stmt.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/Stmt.cpp
clang/lib/Sema/SemaExceptionSpec.cpp
clang/test/SemaCXX/cxx0x-noexcept-expression.cpp

Removed: 




diff  --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h
index 7aebbf2cb6a3..eaacb1a5b252 100644
--- a/clang/include/clang/AST/Stmt.h
+++ b/clang/include/clang/AST/Stmt.h
@@ -1995,6 +1995,10 @@ class IfStmt final
   bool isConstexpr() const { return IfStmtBits.IsConstexpr; }
   void setConstexpr(bool C) { IfStmtBits.IsConstexpr = C; }
 
+  /// If this is an 'if constexpr', determine which substatement will be taken.
+  /// Otherwise, or if the condition is value-dependent, returns None.
+  Optional getNondiscardedCase(const ASTContext &Ctx) const;
+
   bool isObjCAvailabilityCheck() const;
 
   SourceLocation getBeginLoc() const { return getIfLoc(); }

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 6d0f79a2d2ce..6b561dce3e8d 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1599,7 +1599,7 @@ class Sema final {
   DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name);
   static QualType GetTypeFromParser(ParsedType Ty,
 TypeSourceInfo **TInfo = nullptr);
-  CanThrowResult canThrow(const Expr *E);
+  CanThrowResult canThrow(const Stmt *E);
   const FunctionProtoType *ResolveExceptionSpec(SourceLocation Loc,
 const FunctionProtoType *FPT);
   void UpdateExceptionSpec(FunctionDecl *FD,

diff  --git a/clang/lib/AST/Stmt.cpp b/clang/lib/AST/Stmt.cpp
index 80a1451ac789..b6e4d8aff21e 100644
--- a/clang/lib/AST/Stmt.cpp
+++ b/clang/lib/AST/Stmt.cpp
@@ -908,6 +908,12 @@ bool IfStmt::isObjCAvailabilityCheck() const {
   return isa(getCond());
 }
 
+Optional IfStmt::getNondiscardedCase(const ASTContext &Ctx) const 
{
+  if (!isConstexpr() || getCond()->isValueDependent())
+return None;
+  return !getCond()->EvaluateKnownConstInt(Ctx) ? getElse() : getThen();
+}
+
 ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
  Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
  SourceLocation RP)

diff  --git a/clang/lib/Sema/SemaExceptionSpec.cpp 
b/clang/lib/Sema/SemaExceptionSpec.cpp
index c1abf099e9f2..38b9cebb6186 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -15,6 +15,7 @@
 #include "clang/AST/CXXInheritance.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/AST/StmtObjC.h"
 #include "clang/AST/TypeLoc.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
@@ -970,17 +971,22 @@ bool Sema::CheckOverridingFunctionExceptionSpec(const 
CXXMethodDecl *New,
   New->getLocation());
 }
 
-static CanThrowResult canSubExprsThrow(Sema &S, const Expr *E) {
+static CanThrowResult canSubStmtsThrow(Sema &Self, const Stmt *S) {
   CanThrowResult R = CT_Cannot;
-  for (const Stmt *SubStmt : E->children()) {
-R = mergeCanThrow(R, S.canThrow(cast(SubStmt)));
+  for (const Stmt *SubStmt : S->children()) {
+if (!SubStmt)
+  continue;
+R = mergeCanThrow(R, Self.canThrow(SubStmt));
 if (R == CT_Can)
   break;
   }
   return R;
 }
 
-static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D) {
+/// Determine whether the callee of a particular function call can throw.
+/// E and D are both optional, but at least one of E and Loc must be specified.
+static CanThrowResult canCalleeThrow(Sema &S, const Expr *E, const Decl *D,
+ SourceLocation Loc = SourceLocation()) {
   // As an extension, we assume that __attribute__((nothrow)) functions don't
   // throw.
   if (D && isa(D) && D->hasAttr())
@@ -989,7 +995,7 @@ static CanThrowResult canCalleeThrow(Sema &S, const Expr 
*E, const Decl *D) {
   QualType T;
 
   // In C++1z, just look at the function type of the callee.
-  if (S.getLangOpts().CPlusPlus17 && isa(E)) {
+  if (S.getLangOpts().CPlusPlus17 && E && isa(E)) {
 E = cast(E)->getCallee();
 T = E->getType();
   

[PATCH] D71533: [clangd] Show template arguments in type hierarchy when possible

2019-12-15 Thread Nathan Ridge via Phabricator via cfe-commits
nridge created this revision.
nridge added a reviewer: sammccall.
Herald added subscribers: cfe-commits, usaxena95, kadircet, arphaman, jkorous, 
MaskRay, ilya-biryukov.
Herald added a project: clang.

Fixes https://github.com/clangd/clangd/issues/31


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D71533

Files:
  clang-tools-extra/clangd/XRefs.cpp
  clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp


Index: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
===
--- clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
+++ clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
@@ -409,17 +409,13 @@
   ASSERT_TRUE(!AST.getDiagnostics().empty());
 
   // Make sure getTypeHierarchy() doesn't get into an infinite recursion.
-  // FIXME(nridge): It would be preferable if the type hierarchy gave us type
-  // names (e.g. "S<0>" for the child and "S<1>" for the parent) rather than
-  // template names (e.g. "S").
+  // Here, we actually don't get any parents, because the unbounded hierarchy
+  // causes instantiation of the base specifier to fail.
   llvm::Optional Result = getTypeHierarchy(
   AST, Source.points()[0], 0, TypeHierarchyDirection::Parents);
   ASSERT_TRUE(bool(Result));
-  EXPECT_THAT(
-  *Result,
-  AllOf(WithName("S"), WithKind(SymbolKind::Struct),
-Parents(AllOf(WithName("S"), WithKind(SymbolKind::Struct),
-  SelectionRangeIs(Source.range("SDef")), 
Parents();
+  EXPECT_THAT(*Result,
+  AllOf(WithName("S<0>"), WithKind(SymbolKind::Struct), 
Parents()));
 }
 
 TEST(TypeHierarchy, RecursiveHierarchyBounded) {
@@ -449,9 +445,12 @@
   ASSERT_TRUE(bool(Result));
   EXPECT_THAT(
   *Result,
-  AllOf(WithName("S"), WithKind(SymbolKind::Struct),
-Parents(AllOf(WithName("S"), WithKind(SymbolKind::Struct),
-  SelectionRangeIs(Source.range("SDef")), 
Parents();
+  AllOf(WithName("S<2>"), WithKind(SymbolKind::Struct),
+Parents(AllOf(
+WithName("S<1>"), WithKind(SymbolKind::Struct),
+SelectionRangeIs(Source.range("SDef")),
+Parents(AllOf(WithName("S<0>"), WithKind(SymbolKind::Struct),
+  Parents()));
   Result = getTypeHierarchy(AST, Source.point("SRefDependent"), 0,
 TypeHierarchyDirection::Parents);
   ASSERT_TRUE(bool(Result));
Index: clang-tools-extra/clangd/XRefs.cpp
===
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -674,9 +674,19 @@
   const SourceManager &SM = AST.getSourceManager();
   SourceLocation SourceLocationBeg = SM.getMacroArgExpandedLocation(
   getBeginningOfIdentifier(Pos, SM, AST.getLangOpts()));
+  // First, try to find a template instantiation. This will give us
+  // the ClassTemplateSpecializationDecl for a non-dependent
+  // specialization, allowing us to produce a more accurate type
+  // hierarchy specific to that specialization.
   DeclRelationSet Relations =
-  DeclRelation::TemplatePattern | DeclRelation::Underlying;
+  DeclRelation::TemplateInstantiation | DeclRelation::Underlying;
   auto Decls = getDeclAtPosition(AST, SourceLocationBeg, Relations);
+  if (Decls.empty()) {
+// For a dependent specialization, there is no specialization Decl
+// to produce, so get the template pattern instead.
+Relations = DeclRelation::TemplatePattern | DeclRelation::Underlying;
+Decls = getDeclAtPosition(AST, SourceLocationBeg, Relations);
+  }
   if (Decls.empty())
 return nullptr;
 


Index: clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
===
--- clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
+++ clang-tools-extra/clangd/unittests/TypeHierarchyTests.cpp
@@ -409,17 +409,13 @@
   ASSERT_TRUE(!AST.getDiagnostics().empty());
 
   // Make sure getTypeHierarchy() doesn't get into an infinite recursion.
-  // FIXME(nridge): It would be preferable if the type hierarchy gave us type
-  // names (e.g. "S<0>" for the child and "S<1>" for the parent) rather than
-  // template names (e.g. "S").
+  // Here, we actually don't get any parents, because the unbounded hierarchy
+  // causes instantiation of the base specifier to fail.
   llvm::Optional Result = getTypeHierarchy(
   AST, Source.points()[0], 0, TypeHierarchyDirection::Parents);
   ASSERT_TRUE(bool(Result));
-  EXPECT_THAT(
-  *Result,
-  AllOf(WithName("S"), WithKind(SymbolKind::Struct),
-Parents(AllOf(WithName("S"), WithKind(SymbolKind::Struct),
-  SelectionRangeIs(Source.range("SDef")), Parents();
+  EXPECT_THAT(*Result,
+  AllOf(WithName("S<0>"), WithKind(SymbolKind::Struct), Parents()));
 }
 
 TEST(TypeHierarchy, RecursiveHierarchy

[clang] bc633a4 - Mark the major papers for C++20 consistent comparisons as "done", and

2019-12-15 Thread Richard Smith via cfe-commits

Author: Richard Smith
Date: 2019-12-15T22:20:06-08:00
New Revision: bc633a42dd409dbeb456263e3388b8caa4680aa0

URL: 
https://github.com/llvm/llvm-project/commit/bc633a42dd409dbeb456263e3388b8caa4680aa0
DIFF: 
https://github.com/llvm/llvm-project/commit/bc633a42dd409dbeb456263e3388b8caa4680aa0.diff

LOG: Mark the major papers for C++20 consistent comparisons as "done", and
start publishing the corresponding feature-test macro.

Added: 


Modified: 
clang/lib/Frontend/InitPreprocessor.cpp
clang/test/Lexer/cxx-features.cpp
clang/www/cxx_status.html

Removed: 




diff  --git a/clang/lib/Frontend/InitPreprocessor.cpp 
b/clang/lib/Frontend/InitPreprocessor.cpp
index b1c7aed0d44e..79360f89fc82 100644
--- a/clang/lib/Frontend/InitPreprocessor.cpp
+++ b/clang/lib/Frontend/InitPreprocessor.cpp
@@ -546,6 +546,7 @@ static void InitializeCPlusPlusFeatureTestMacros(const 
LangOptions &LangOpts,
 Builder.defineMacro("__cpp_conditional_explicit", "201806L");
 Builder.defineMacro("__cpp_constexpr_dynamic_alloc", "201907L");
 Builder.defineMacro("__cpp_constinit", "201907L");
+Builder.defineMacro("__cpp_impl_three_way_comparison", "201907L");
   }
   if (LangOpts.Char8)
 Builder.defineMacro("__cpp_char8_t", "201811L");

diff  --git a/clang/test/Lexer/cxx-features.cpp 
b/clang/test/Lexer/cxx-features.cpp
index 868ec24a1d9f..077f3155fee9 100644
--- a/clang/test/Lexer/cxx-features.cpp
+++ b/clang/test/Lexer/cxx-features.cpp
@@ -46,6 +46,10 @@
 #error "wrong value for __cpp_impl_destroying_delete"
 #endif
 
+#if check(impl_three_way_comparison, 0, 0, 0, 0, 201907)
+#error "wrong value for __cpp_impl_three_way_comparison"
+#endif
+
 // --- C++17 features ---
 
 #if check(hex_float, 0, 0, 0, 201603, 201603)

diff  --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
index 47f58727def8..3f7cfd1308bf 100755
--- a/clang/www/cxx_status.html
+++ b/clang/www/cxx_status.html
@@ -926,11 +926,10 @@ C++2a implementation status
 
   Consistent comparison (operator<=>)
   https://wg21.link/p0515r3";>P0515R3
-  Partial
+  SVN
 

 https://wg21.link/p0905r1";>P0905R1
-SVN
   

 https://wg21.link/p1120r0";>P1120R0



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