[PATCH] D50606: [ASTMatchers] Add matchers unresolvedMemberExpr, cxxDependentScopeMemberExpr

2018-08-12 Thread Shuai Wang via Phabricator via cfe-commits
shuaiwang created this revision.
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D50606

Files:
  docs/LibASTMatchersReference.html
  include/clang/ASTMatchers/ASTMatchers.h
  lib/ASTMatchers/ASTMatchersInternal.cpp
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/AST/ASTImporterTest.cpp
  unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Index: unittests/ASTMatchers/ASTMatchersNodeTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -422,10 +422,17 @@
 
 TEST(MemberExpression, DoesNotMatchClasses) {
   EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
+  EXPECT_TRUE(notMatches("class Y { void x() {} };", unresolvedMemberExpr()));
+  EXPECT_TRUE(
+  notMatches("class Y { void x() {} };", cxxDependentScopeMemberExpr()));
 }
 
 TEST(MemberExpression, MatchesMemberFunctionCall) {
   EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
+  EXPECT_TRUE(matches("class Y { template  void x() { x(); } };",
+  unresolvedMemberExpr()));
+  EXPECT_TRUE(matches("template  void x() { T t; t.f(); }",
+  cxxDependentScopeMemberExpr()));
 }
 
 TEST(MemberExpression, MatchesVariable) {
@@ -435,6 +442,13 @@
 matches("class Y { void x() { y; } int y; };", memberExpr()));
   EXPECT_TRUE(
 matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
+  EXPECT_TRUE(matches("template "
+  "class X : T { void f() { this->T::v; } };",
+  cxxDependentScopeMemberExpr()));
+  EXPECT_TRUE(matches("template  class X : T { void f() { T::v; } };",
+  cxxDependentScopeMemberExpr()));
+  EXPECT_TRUE(matches("template  void x() { T t; t.v; }",
+  cxxDependentScopeMemberExpr()));
 }
 
 TEST(MemberExpression, MatchesStaticVariable) {
Index: unittests/AST/ASTImporterTest.cpp
===
--- unittests/AST/ASTImporterTest.cpp
+++ unittests/AST/ASTImporterTest.cpp
@@ -814,9 +814,6 @@
   functionTemplateDecl());
 }
 
-const internal::VariadicDynCastAllOfMatcher
-cxxDependentScopeMemberExpr;
-
 TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) {
   MatchVerifier Verifier;
   testImport(
@@ -2364,9 +2361,6 @@
  cxxRecordDecl(has(typedefDecl(has(dependentNameType(;
 }
 
-const internal::VariadicDynCastAllOfMatcher
-unresolvedMemberExpr;
-
 TEST_P(ImportExpr, UnresolvedMemberExpr) {
   MatchVerifier Verifier;
   testImport("struct S { template  void mem(); };"
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -167,6 +167,7 @@
   REGISTER_MATCHER(cxxCtorInitializer);
   REGISTER_MATCHER(cxxDefaultArgExpr);
   REGISTER_MATCHER(cxxDeleteExpr);
+  REGISTER_MATCHER(cxxDependentScopeMemberExpr);
   REGISTER_MATCHER(cxxDestructorDecl);
   REGISTER_MATCHER(cxxDynamicCastExpr);
   REGISTER_MATCHER(cxxForRangeStmt);
@@ -475,6 +476,7 @@
   REGISTER_MATCHER(unaryTransformType);
   REGISTER_MATCHER(unless);
   REGISTER_MATCHER(unresolvedLookupExpr);
+  REGISTER_MATCHER(unresolvedMemberExpr);
   REGISTER_MATCHER(unresolvedUsingTypenameDecl);
   REGISTER_MATCHER(unresolvedUsingValueDecl);
   REGISTER_MATCHER(userDefinedLiteral);
Index: lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- lib/ASTMatchers/ASTMatchersInternal.cpp
+++ lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -610,6 +610,10 @@
 const internal::VariadicAllOfMatcher stmt;
 const internal::VariadicDynCastAllOfMatcher declStmt;
 const internal::VariadicDynCastAllOfMatcher memberExpr;
+const internal::VariadicDynCastAllOfMatcher
+unresolvedMemberExpr;
+const internal::VariadicDynCastAllOfMatcher
+cxxDependentScopeMemberExpr;
 const internal::VariadicDynCastAllOfMatcher callExpr;
 const internal::VariadicDynCastAllOfMatcher lambdaExpr;
 const internal::VariadicDynCastAllOfMatcher
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -1141,6 +1141,34 @@
 ///   matches this->x, x, y.x, a, this->b
 extern const internal::VariadicDynCastAllOfMatcher memberExpr;
 
+/// Matches unresolved member expressions.
+///
+/// Given
+/// \code
+///   struct X {
+/// template  void f();
+/// void g();
+///   };
+///   template  void h() { X x; x.f(); x.g(); }
+/// \endcode
+/// unresolvedMemberExpr()
+///   matches x.f
+extern const internal::VariadicDynCastAllOfMatcher
+unresolvedMemberExpr;
+
+/// Matches member expressions where the actual member referenced could not be
+/// resolved because the base expression or the me

[PATCH] D50606: [ASTMatchers] Add matchers unresolvedMemberExpr, cxxDependentScopeMemberExpr

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM, but please split out the unrelated changes into their own commit.




Comment at: docs/LibASTMatchersReference.html:1168-1173
+MatcherStmt>imaginaryLiteralMatcherImaginaryLiteral>...
+Matches imaginary 
literals, which are based on integer and floating
+point literals e.g.: 1i, 1.0i
+
+
+

This change looks unrelated to your patch.



Comment at: docs/LibASTMatchersReference.html:1280
 }
-}
 

This change looks unrelated to your patch.


Repository:
  rC Clang

https://reviews.llvm.org/D50606



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


[PATCH] D50605: [ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman requested changes to this revision.
aaron.ballman added a comment.
This revision now requires changes to proceed.

Please be sure to regenerate the AST matcher documentation as well, as I'd 
expect to see some documentation changes from this.




Comment at: include/clang/AST/ExprCXX.h:3436
   using const_arg_iterator = const Expr* const *;
+  using arg_const_range = llvm::iterator_range;
 

Please name this `const_arg_range` for consistency.


Repository:
  rC Clang

https://reviews.llvm.org/D50605



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


[PATCH] D49114: [clang-tidy] Add a check for "magic numbers"

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

Alex has had plenty of time to respond, so I'm fine handling any concerns he 
has post-commit. Do you need me to commit this on your behalf?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D49114



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


[PATCH] D49114: [clang-tidy] Add a check for "magic numbers"

2018-08-12 Thread Florin Iucha via Phabricator via cfe-commits
0x8000- added a comment.

In https://reviews.llvm.org/D49114#1196480, @aaron.ballman wrote:

> Alex has had plenty of time to respond, so I'm fine handling any concerns he 
> has post-commit. Do you need me to commit this on your behalf?


Yes, please! Thank you!

Author: "Florin Iucha "


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D49114



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


[PATCH] D50580: [clang-tidy] Abseil: no namespace check

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang-tidy/abseil/NoNamespaceCheck.cpp:23
+
+  Finder->addMatcher(namespaceDecl(hasName("absl")).bind("absl_namespace"),
+ this);

I think this needs a `not(isExpansionInSystemHeader())` in there, as this is 
going to trigger on code that includes a header file using an `absl` namespace. 
If I'm incorrect and users typically include abseil as something other than 
system includes, you'll have to find a different way to solve this.



Comment at: clang-tidy/abseil/NoNamespaceCheck.cpp:32
+   "namespace 'absl' is reserved for implementation of the Abseil library "
+   "and should not be opened in the user code");
+}

in the user code -> in user code

Does Abseil prohibit the user from specializing templates in the `absl` 
namespace with user-defined types?


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50580



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


[PATCH] D50542: [clang-tidy] Add abseil-no-internal-deps check

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang-tidy/abseil/NoInternalDepsCheck.cpp:24
+
+  // TODO(hugoeg): refactor matcher to be configurable or just match on any 
internal access from outside the enclosing namespace.
+  

JonasToth wrote:
> Nit: This comment is very long, pls break the line
Also, we don't add developer names to comments.



Comment at: clang-tidy/abseil/NoInternalDepsCheck.cpp:39-41
+   "depends upon internal implementation details, which violates the "
+   "Abseil compatibilty guidelines. See "
+   "https://abseil.io/about/compatibility";);

Diagnostic text is not supposed to be grammatically correct with capitalization 
and punctuation. Please do not put links into diagnostics. It's more 
appropriate for this to be in the documentation. I think this might be improved 
wording: `do not reference the 'internal' namespace; those implementation 
details are reserved to Abeil` or something along those lines.



Comment at: clang-tidy/abseil/NoInternalDepsCheck.h:19-21
+/// Finds instances where the user depends on internal details and warns them
+/// against doing so.
+/// This check should not be run on internal Abseil files or Abseil source 
code.

Can you re-flow these comments?



Comment at: docs/clang-tidy/checks/abseil-no-internal-deps.rst:6
+
+Gives a warning if code using Abseil depends on internal details. If something 
is in a namespace or filename/path that includes the word “internal”, code is 
not allowed to depend upon it beaucse it’s an implementation detail. They 
cannot friend it, include it, you mention it or refer to it in any way. Doing 
so violtaes Abseil's compatibility guidelines and may result in breakage.
+

JonasToth wrote:
> s/violtaes/violates/
Please wrap lines to 80 cols.

Nothing in this check looks at filenames and paths, but this suggests the check 
will find those. Is that intended work that's missed in this patch, or are the 
docs incorrect?


https://reviews.llvm.org/D50542



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


[PATCH] D50580: [clang-tidy] Abseil: no namespace check

2018-08-12 Thread Roman Lebedev via Phabricator via cfe-commits
lebedev.ri added a comment.

> We are aware that this test will cause warnings on users code through their 
> dependencies on abseil.
>  However, from what we know it seems like these warnings are normally 
> suppressed.
>  If anyone has a good idea on how to avoid this/has insight on whether this 
> will be a problem for the average user, please let me know!

Suppressed how?
I think this needs tests.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50580



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


[clang-tools-extra] r339516 - Add a new check to the readability module that flags uses of "magic numbers" (both floating-point and integral).

2018-08-12 Thread Aaron Ballman via cfe-commits
Author: aaronballman
Date: Sun Aug 12 07:35:13 2018
New Revision: 339516

URL: http://llvm.org/viewvc/llvm-project?rev=339516&view=rev
Log:
Add a new check to the readability module that flags uses of "magic numbers" 
(both floating-point and integral).

Patch by Florin Iucha 

Added:
clang-tools-extra/trunk/clang-tidy/readability/MagicNumbersCheck.cpp
clang-tools-extra/trunk/clang-tidy/readability/MagicNumbersCheck.h

clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-avoid-magic-numbers.rst
clang-tools-extra/trunk/docs/clang-tidy/checks/readability-magic-numbers.rst
clang-tools-extra/trunk/test/clang-tidy/readability-magic-numbers.cpp
Modified:

clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt
clang-tools-extra/trunk/clang-tidy/readability/ReadabilityTidyModule.cpp
clang-tools-extra/trunk/docs/ReleaseNotes.rst
clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp?rev=339516&r1=339515&r2=339516&view=diff
==
--- 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
 (original)
+++ 
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
 Sun Aug 12 07:35:13 2018
@@ -11,6 +11,7 @@
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
 #include "../misc/UnconventionalAssignOperatorCheck.h"
+#include "../readability/MagicNumbersCheck.h"
 #include "AvoidGotoCheck.h"
 #include "InterfacesGlobalInitCheck.h"
 #include "NarrowingConversionsCheck.h"
@@ -41,6 +42,8 @@ public:
 "cppcoreguidelines-avoid-goto");
 CheckFactories.registerCheck(
 "cppcoreguidelines-interfaces-global-init");
+CheckFactories.registerCheck(
+"cppcoreguidelines-avoid-magic-numbers");
 CheckFactories.registerCheck(
 "cppcoreguidelines-narrowing-conversions");
 CheckFactories.registerCheck("cppcoreguidelines-no-malloc");

Modified: clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt?rev=339516&r1=339515&r2=339516&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/readability/CMakeLists.txt Sun Aug 12 
07:35:13 2018
@@ -11,6 +11,7 @@ add_clang_library(clangTidyReadabilityMo
   IdentifierNamingCheck.cpp
   ImplicitBoolConversionCheck.cpp
   InconsistentDeclarationParameterNameCheck.cpp
+  MagicNumbersCheck.cpp
   MisleadingIndentationCheck.cpp
   MisplacedArrayIndexCheck.cpp
   NamedParameterCheck.cpp

Added: clang-tools-extra/trunk/clang-tidy/readability/MagicNumbersCheck.cpp
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/readability/MagicNumbersCheck.cpp?rev=339516&view=auto
==
--- clang-tools-extra/trunk/clang-tidy/readability/MagicNumbersCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/readability/MagicNumbersCheck.cpp Sun 
Aug 12 07:35:13 2018
@@ -0,0 +1,171 @@
+//===--- MagicNumbersCheck.cpp - clang-tidy---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// A checker for magic numbers: integer or floating point literals embedded
+// in the code, outside the definition of a constant or an enumeration.
+//
+//===--===//
+
+#include "MagicNumbersCheck.h"
+#include "../utils/OptionsUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "llvm/ADT/STLExtras.h"
+#include 
+
+using namespace clang::ast_matchers;
+using namespace clang::ast_type_traits;
+
+namespace {
+
+bool isUsedToInitializeAConstant(const MatchFinder::MatchResult &Result,
+ const DynTypedNode &Node) {
+
+  const auto *AsDecl = Node.get();
+  if (AsDecl) {
+if (AsDecl->getType().isConstQualified())
+  return true;
+
+return AsDecl->isImplicit();
+  }
+
+  if (Node.get() != nullptr)
+return true;
+
+  return llvm::any_of(Result.Context->getParents(Node),
+  [&Result](const DynTypedNode &Parent) {
+return isUsedToInitializeAConstant(Result, Parent);
+  });
+}
+

[PATCH] D49114: [clang-tidy] Add a check for "magic numbers"

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman closed this revision.
aaron.ballman added a comment.

Thank you for the patch and great discussion! I've commit in r339516.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D49114



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


[PATCH] D50467: [SEMA] add more -Wfloat-conversion to compound assigment analysis

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM!


Repository:
  rC Clang

https://reviews.llvm.org/D50467



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


[clang-tools-extra] r339517 - Adding the readability module to the list of dependencies for the C++ Core Guidelines module. Amends r339516 for a failing bot.

2018-08-12 Thread Aaron Ballman via cfe-commits
Author: aaronballman
Date: Sun Aug 12 07:47:16 2018
New Revision: 339517

URL: http://llvm.org/viewvc/llvm-project?rev=339517&view=rev
Log:
Adding the readability module to the list of dependencies for the C++ Core 
Guidelines module. Amends r339516 for a failing bot.

Modified:
clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt

Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt
URL: 
http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt?rev=339517&r1=339516&r2=339517&view=diff
==
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt 
(original)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CMakeLists.txt Sun Aug 
12 07:47:16 2018
@@ -27,6 +27,7 @@ add_clang_library(clangTidyCppCoreGuidel
   clangLex
   clangTidy
   clangTidyMiscModule
+  clangTidyReadabilityModule
   clangTidyUtils
   clangTooling
   )


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


[PATCH] D50526: Model type attributes as regular Attrs

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM! Thank you for this fantastic work!




Comment at: include/clang/Basic/Attr.td:1510
+  let Spellings = [Keyword<"__unsafe_unretained">];
+  let Documentation = [Undocumented];
+}

rsmith wrote:
> aaron.ballman wrote:
> > I don't suppose you can throw in some quick docs for this keyword? Or is 
> > this not really user-facing? If it's not user-facing, perhaps it should 
> > have no spellings and only ever be created implicitly?
> This isn't actually the primary representation of `__unsafe_unretained`, this 
> is an internal placeholder for "the user wrote `__unsafe_unretained` but 
> we're not in ARC mode so it's meaningless (hence "inert")". So I don't think 
> this is where we should attach the documentation (the right place is the 
> `ObjCOwnership` attribute, which is also currently `Undocumented`, sadly). 
> I'll at least add a comment to the .td file to explain that.
Ah, thank you for the explanation; I agree.



Comment at: lib/AST/Type.cpp:1624
+  const Type *Cur = this;
+  while (auto *AT = Cur->getAs()) {
+if (AT->getAttrKind() == AK)

rsmith wrote:
> aaron.ballman wrote:
> > `const auto *`
> Done, but...
> 
> The pointee type is deduced as `const` anyway, so the `const` doesn't give 
> any extra type safety. So the only benefit would be to the reader, and I 
> don't think a reader of this code would care whether `*AT` is mutable, so the 
> `const` seems like a distraction to me (and hence the explicit `const` is a 
> minor harm to readability rather than a minor improvement). I can see how a 
> reader trained to think that absence-of-`const` implies that mutation is 
> intended would find the explicit `const` clearer, but (for better or probably 
> worse) that's not the style we generally use in Clang (for instance, I didn't 
> mark the `AK` parameter as `const`, but there is no implication that I intend 
> to modify it).
> 
> That said, I don't feel strongly about this, and I certainly have no 
> objection to making the change here. If we generally want to move to a style 
> where `auto` is always accompanied by an explicit `const` when `const` would 
> be deduced (in much the same way that we already expect that `auto` be 
> accompanied by an explicit `*` when a pointer type would be deduced), I'd be 
> OK with that -- but we should discuss that somewhere more visible than this 
> review thread and include it in our general coding guidelines.
> That said, I don't feel strongly about this, and I certainly have no 
> objection to making the change here. If we generally want to move to a style 
> where auto is always accompanied by an explicit const when const would be 
> deduced (in much the same way that we already expect that auto be accompanied 
> by an explicit * when a pointer type would be deduced), I'd be OK with that 
> -- but we should discuss that somewhere more visible than this review thread 
> and include it in our general coding guidelines.

Yeah, I actually thought this already was part of the coding guidelines, truth 
be told. But I went and looked again and realized we only talk about `*` and 
`&` being deduced, not qualifiers. I guess my preference has always been to 
explicitly spell out pertinent information about the type beyond the name, such 
as whether it's `const`, whether it's a pointer, etc. Basically, things that 
aren't immediately obvious from the context.

I prefer being explicit about spelling out the `const` here because it makes it 
obvious that the type is not intended to be mutated, but I only really care 
about it in cases where the type is deduced to a pointer or reference (and so 
mutating operations might be hidden behind a function call that looks harmless).

Perhaps this is worth starting a coding guideline discussion over?



Comment at: lib/Sema/SemaType.cpp:3884
 
+template
+static AttrT *createSimpleAttr(ASTContext &Ctx, ParsedAttr &Attr) {

rsmith wrote:
> aaron.ballman wrote:
> > Did clang-format do this? It seems like it's not formatted how I'd expect.
> How would you expect it? clang-format puts a space after the `template` 
> keyword, unfortunately, and IIRC can't be configured to not do so. Though as 
> a consequence, it looks like the space is now more common in clang code by a 
> 2:1 ratio despite being "clearly wrong" ;-(
I was expecting to see a space after `template` as I thought that was the most 
common form of it in the code base. :-D



Comment at: lib/Sema/SemaType.cpp:6360
+  }
+}
+

rsmith wrote:
> aaron.ballman wrote:
> > MSVC may complain about not all control paths returning a value here.
> I'm confident that this pattern is fine; we use it all over the place. MSVC 
> knows that control flow cannot leave an `llvm_unreachable(...)`.
Yeah, I think I was mis-remembering a pattern t

[PATCH] D50214: Add inherited attributes before parsed attributes.

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added subscribers: rsmith, echristo, dlj, nicholas.
aaron.ballman edited reviewers, added: rsmith; removed: nicholas, dlj, echristo.
aaron.ballman added a comment.

In general, I think this is the right way to go. I've added @rsmith to the 
reviewers because I'm curious what his thoughts are on this approach, though.




Comment at: lib/AST/DeclBase.cpp:854-859
+  auto I = Attrs.begin(), E = Attrs.end();
+  for (; I != E; ++I) {
+if (!(*I)->isInherited())
+  break;
+  }
+  Attrs.insert(I, A);

The unfortunate part about this is that inherited attributes are fairly common, 
so this extra searching may happen more often than we'd like. I wonder how bad 
it would be to keep track of the location within the list where the inherited 
attributes start. Then again, the list of attributes should be relatively short 
in most cases, so this search isn't likely to be too expensive.

Having some performance measurements might help decide this, too.


Repository:
  rC Clang

https://reviews.llvm.org/D50214



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


[PATCH] D49910: [clang-tidy] Recognize [[clang::reinitializes]] attribute in bugprone-use-after-move

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM! An attribute really is the right way to go for this sort of thing, and it 
sounds like you've got a base of users looking for the functionality.


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D49910



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


[PATCH] D50606: [ASTMatchers] Add matchers unresolvedMemberExpr, cxxDependentScopeMemberExpr

2018-08-12 Thread Shuai Wang via Phabricator via cfe-commits
shuaiwang updated this revision to Diff 160263.
shuaiwang marked 2 inline comments as done.
shuaiwang added a comment.

undo unrelated changes in doc


Repository:
  rC Clang

https://reviews.llvm.org/D50606

Files:
  docs/LibASTMatchersReference.html
  include/clang/ASTMatchers/ASTMatchers.h
  lib/ASTMatchers/ASTMatchersInternal.cpp
  lib/ASTMatchers/Dynamic/Registry.cpp
  unittests/AST/ASTImporterTest.cpp
  unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Index: unittests/ASTMatchers/ASTMatchersNodeTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -422,10 +422,17 @@
 
 TEST(MemberExpression, DoesNotMatchClasses) {
   EXPECT_TRUE(notMatches("class Y { void x() {} };", memberExpr()));
+  EXPECT_TRUE(notMatches("class Y { void x() {} };", unresolvedMemberExpr()));
+  EXPECT_TRUE(
+  notMatches("class Y { void x() {} };", cxxDependentScopeMemberExpr()));
 }
 
 TEST(MemberExpression, MatchesMemberFunctionCall) {
   EXPECT_TRUE(matches("class Y { void x() { x(); } };", memberExpr()));
+  EXPECT_TRUE(matches("class Y { template  void x() { x(); } };",
+  unresolvedMemberExpr()));
+  EXPECT_TRUE(matches("template  void x() { T t; t.f(); }",
+  cxxDependentScopeMemberExpr()));
 }
 
 TEST(MemberExpression, MatchesVariable) {
@@ -435,6 +442,13 @@
 matches("class Y { void x() { y; } int y; };", memberExpr()));
   EXPECT_TRUE(
 matches("class Y { void x() { Y y; y.y; } int y; };", memberExpr()));
+  EXPECT_TRUE(matches("template "
+  "class X : T { void f() { this->T::v; } };",
+  cxxDependentScopeMemberExpr()));
+  EXPECT_TRUE(matches("template  class X : T { void f() { T::v; } };",
+  cxxDependentScopeMemberExpr()));
+  EXPECT_TRUE(matches("template  void x() { T t; t.v; }",
+  cxxDependentScopeMemberExpr()));
 }
 
 TEST(MemberExpression, MatchesStaticVariable) {
Index: unittests/AST/ASTImporterTest.cpp
===
--- unittests/AST/ASTImporterTest.cpp
+++ unittests/AST/ASTImporterTest.cpp
@@ -814,9 +814,6 @@
   functionTemplateDecl());
 }
 
-const internal::VariadicDynCastAllOfMatcher
-cxxDependentScopeMemberExpr;
-
 TEST_P(ImportExpr, ImportCXXDependentScopeMemberExpr) {
   MatchVerifier Verifier;
   testImport(
@@ -2364,9 +2361,6 @@
  cxxRecordDecl(has(typedefDecl(has(dependentNameType(;
 }
 
-const internal::VariadicDynCastAllOfMatcher
-unresolvedMemberExpr;
-
 TEST_P(ImportExpr, UnresolvedMemberExpr) {
   MatchVerifier Verifier;
   testImport("struct S { template  void mem(); };"
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -167,6 +167,7 @@
   REGISTER_MATCHER(cxxCtorInitializer);
   REGISTER_MATCHER(cxxDefaultArgExpr);
   REGISTER_MATCHER(cxxDeleteExpr);
+  REGISTER_MATCHER(cxxDependentScopeMemberExpr);
   REGISTER_MATCHER(cxxDestructorDecl);
   REGISTER_MATCHER(cxxDynamicCastExpr);
   REGISTER_MATCHER(cxxForRangeStmt);
@@ -475,6 +476,7 @@
   REGISTER_MATCHER(unaryTransformType);
   REGISTER_MATCHER(unless);
   REGISTER_MATCHER(unresolvedLookupExpr);
+  REGISTER_MATCHER(unresolvedMemberExpr);
   REGISTER_MATCHER(unresolvedUsingTypenameDecl);
   REGISTER_MATCHER(unresolvedUsingValueDecl);
   REGISTER_MATCHER(userDefinedLiteral);
Index: lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- lib/ASTMatchers/ASTMatchersInternal.cpp
+++ lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -610,6 +610,10 @@
 const internal::VariadicAllOfMatcher stmt;
 const internal::VariadicDynCastAllOfMatcher declStmt;
 const internal::VariadicDynCastAllOfMatcher memberExpr;
+const internal::VariadicDynCastAllOfMatcher
+unresolvedMemberExpr;
+const internal::VariadicDynCastAllOfMatcher
+cxxDependentScopeMemberExpr;
 const internal::VariadicDynCastAllOfMatcher callExpr;
 const internal::VariadicDynCastAllOfMatcher lambdaExpr;
 const internal::VariadicDynCastAllOfMatcher
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -1141,6 +1141,34 @@
 ///   matches this->x, x, y.x, a, this->b
 extern const internal::VariadicDynCastAllOfMatcher memberExpr;
 
+/// Matches unresolved member expressions.
+///
+/// Given
+/// \code
+///   struct X {
+/// template  void f();
+/// void g();
+///   };
+///   template  void h() { X x; x.f(); x.g(); }
+/// \endcode
+/// unresolvedMemberExpr()
+///   matches x.f
+extern const internal::VariadicDynCastAllOfMatcher
+unresolvedMemberExpr;
+
+/// Matches member expressions where the actual memb

r339522 - [ASTMatchers] Add matchers unresolvedMemberExpr, cxxDependentScopeMemberExpr

2018-08-12 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Sun Aug 12 10:34:36 2018
New Revision: 339522

URL: http://llvm.org/viewvc/llvm-project?rev=339522&view=rev
Log:
[ASTMatchers] Add matchers unresolvedMemberExpr, cxxDependentScopeMemberExpr

Subscribers: cfe-commits

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

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
cfe/trunk/unittests/AST/ASTImporterTest.cpp
cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=339522&r1=339521&r2=339522&view=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Sun Aug 12 10:34:36 2018
@@ -866,6 +866,17 @@ cxxDeleteExpr()
 
 
 
+MatcherStmt>cxxDependentScopeMemberExprMatcherCXXDependentScopeMemberExpr>...
+Matches 
member expressions where the actual member referenced could not be
+resolved because the base expression or the member name was dependent.
+
+Given
+  template  void f() { T t; t.g(); }
+cxxDependentScopeMemberExpr()
+  matches t.g
+
+
+
 MatcherStmt>cxxDynamicCastExprMatcherCXXDynamicCastExpr>...
 Matches a 
dynamic_cast expression.
 
@@ -1455,6 +1466,20 @@ unresolvedLookupExpr()
   matches foo() 
 
 
+MatcherStmt>unresolvedMemberExprMatcherUnresolvedMemberExpr>...
+Matches 
unresolved member expressions.
+
+Given
+  struct X {
+template  void f();
+void g();
+  };
+  template  void h() { X x; x.f(); x.g(); }
+unresolvedMemberExpr()
+  matches x.f
+
+
+
 MatcherStmt>userDefinedLiteralMatcherUserDefinedLiteral>...
 Matches user 
defined literal operator call.
 
@@ -1598,7 +1623,7 @@ Given:
   short i = 1;
   int j = 42;
   decltype(i + j) result = i + j;
-decltypeType() 
+decltypeType()
   matches "decltype(i + j)"
 
 

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=339522&r1=339521&r2=339522&view=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Sun Aug 12 10:34:36 2018
@@ -1141,6 +1141,34 @@ extern const internal::VariadicDynCastAl
 ///   matches this->x, x, y.x, a, this->b
 extern const internal::VariadicDynCastAllOfMatcher 
memberExpr;
 
+/// Matches unresolved member expressions.
+///
+/// Given
+/// \code
+///   struct X {
+/// template  void f();
+/// void g();
+///   };
+///   template  void h() { X x; x.f(); x.g(); }
+/// \endcode
+/// unresolvedMemberExpr()
+///   matches x.f
+extern const internal::VariadicDynCastAllOfMatcher
+unresolvedMemberExpr;
+
+/// Matches member expressions where the actual member referenced could not be
+/// resolved because the base expression or the member name was dependent.
+///
+/// Given
+/// \code
+///   template  void f() { T t; t.g(); }
+/// \endcode
+/// cxxDependentScopeMemberExpr()
+///   matches t.g
+extern const internal::VariadicDynCastAllOfMatcher
+cxxDependentScopeMemberExpr;
+
 /// Matches call expressions.
 ///
 /// Example matches x.y() and y()

Modified: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=339522&r1=339521&r2=339522&view=diff
==
--- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Sun Aug 12 10:34:36 2018
@@ -610,6 +610,10 @@ const internal::VariadicDynCastAllOfMatc
 const internal::VariadicAllOfMatcher stmt;
 const internal::VariadicDynCastAllOfMatcher declStmt;
 const internal::VariadicDynCastAllOfMatcher memberExpr;
+const internal::VariadicDynCastAllOfMatcher
+unresolvedMemberExpr;
+const internal::VariadicDynCastAllOfMatcher
+cxxDependentScopeMemberExpr;
 const internal::VariadicDynCastAllOfMatcher callExpr;
 const internal::VariadicDynCastAllOfMatcher lambdaExpr;
 const internal::VariadicDynCastAllOfMatcher

Modified: cfe/trunk/lib/AST

[PATCH] D50606: [ASTMatchers] Add matchers unresolvedMemberExpr, cxxDependentScopeMemberExpr

2018-08-12 Thread Shuai Wang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL339522: [ASTMatchers] Add matchers unresolvedMemberExpr, 
cxxDependentScopeMemberExpr (authored by shuaiwang, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D50606

Files:
  cfe/trunk/docs/LibASTMatchersReference.html
  cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
  cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
  cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
  cfe/trunk/unittests/AST/ASTImporterTest.cpp
  cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp

Index: cfe/trunk/docs/LibASTMatchersReference.html
===
--- cfe/trunk/docs/LibASTMatchersReference.html
+++ cfe/trunk/docs/LibASTMatchersReference.html
@@ -866,6 +866,17 @@
 
 
 
+MatcherStmt>cxxDependentScopeMemberExprMatcherCXXDependentScopeMemberExpr>...
+Matches member expressions where the actual member referenced could not be
+resolved because the base expression or the member name was dependent.
+
+Given
+  template  void f() { T t; t.g(); }
+cxxDependentScopeMemberExpr()
+  matches t.g
+
+
+
 MatcherStmt>cxxDynamicCastExprMatcherCXXDynamicCastExpr>...
 Matches a dynamic_cast expression.
 
@@ -1455,6 +1466,20 @@
   matches foo() 
 
 
+MatcherStmt>unresolvedMemberExprMatcherUnresolvedMemberExpr>...
+Matches unresolved member expressions.
+
+Given
+  struct X {
+template  void f();
+void g();
+  };
+  template  void h() { X x; x.f(); x.g(); }
+unresolvedMemberExpr()
+  matches x.f
+
+
+
 MatcherStmt>userDefinedLiteralMatcherUserDefinedLiteral>...
 Matches user defined literal operator call.
 
@@ -1598,7 +1623,7 @@
   short i = 1;
   int j = 42;
   decltype(i + j) result = i + j;
-decltypeType() 
+decltypeType()
   matches "decltype(i + j)"
 
 
Index: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
===
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
@@ -1141,6 +1141,34 @@
 ///   matches this->x, x, y.x, a, this->b
 extern const internal::VariadicDynCastAllOfMatcher memberExpr;
 
+/// Matches unresolved member expressions.
+///
+/// Given
+/// \code
+///   struct X {
+/// template  void f();
+/// void g();
+///   };
+///   template  void h() { X x; x.f(); x.g(); }
+/// \endcode
+/// unresolvedMemberExpr()
+///   matches x.f
+extern const internal::VariadicDynCastAllOfMatcher
+unresolvedMemberExpr;
+
+/// Matches member expressions where the actual member referenced could not be
+/// resolved because the base expression or the member name was dependent.
+///
+/// Given
+/// \code
+///   template  void f() { T t; t.g(); }
+/// \endcode
+/// cxxDependentScopeMemberExpr()
+///   matches t.g
+extern const internal::VariadicDynCastAllOfMatcher
+cxxDependentScopeMemberExpr;
+
 /// Matches call expressions.
 ///
 /// Example matches x.y() and y()
Index: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
===
--- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -167,6 +167,7 @@
   REGISTER_MATCHER(cxxCtorInitializer);
   REGISTER_MATCHER(cxxDefaultArgExpr);
   REGISTER_MATCHER(cxxDeleteExpr);
+  REGISTER_MATCHER(cxxDependentScopeMemberExpr);
   REGISTER_MATCHER(cxxDestructorDecl);
   REGISTER_MATCHER(cxxDynamicCastExpr);
   REGISTER_MATCHER(cxxForRangeStmt);
@@ -475,6 +476,7 @@
   REGISTER_MATCHER(unaryTransformType);
   REGISTER_MATCHER(unless);
   REGISTER_MATCHER(unresolvedLookupExpr);
+  REGISTER_MATCHER(unresolvedMemberExpr);
   REGISTER_MATCHER(unresolvedUsingTypenameDecl);
   REGISTER_MATCHER(unresolvedUsingValueDecl);
   REGISTER_MATCHER(userDefinedLiteral);
Index: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
===
--- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -610,6 +610,10 @@
 const internal::VariadicAllOfMatcher stmt;
 const internal::VariadicDynCastAllOfMatcher declStmt;
 const internal::VariadicDynCastAllOfMatcher memberExpr;
+const internal::VariadicDynCastAllOfMatcher
+unresolvedMemberExpr;
+const internal::VariadicDynCastAllOfMatcher
+cxxDependentScopeMemberExpr;
 const interna

[PATCH] D50605: [ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

2018-08-12 Thread Shuai Wang via Phabricator via cfe-commits
shuaiwang updated this revision to Diff 160265.
shuaiwang added a comment.

update ast matchers doc


Repository:
  rC Clang

https://reviews.llvm.org/D50605

Files:
  docs/LibASTMatchersReference.html
  include/clang/AST/ExprCXX.h
  include/clang/ASTMatchers/ASTMatchers.h
  unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -406,16 +406,35 @@
   auto HasArgumentY = hasAnyArgument(
   ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"));
   StatementMatcher CallArgumentY = callExpr(HasArgumentY);
+  StatementMatcher CtorArgumentY = cxxConstructExpr(HasArgumentY);
+  StatementMatcher UnresolvedCtorArgumentY =
+  cxxUnresolvedConstructExpr(HasArgumentY);
   StatementMatcher ObjCCallArgumentY = objcMessageExpr(HasArgumentY);
   EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
   EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
+  EXPECT_TRUE(matches("struct Y { Y(int, int); };"
+  "void x() { int y; (void)Y(1, y); }",
+  CtorArgumentY));
+  EXPECT_TRUE(matches("struct Y { Y(int, int); };"
+  "void x() { int y; (void)Y(y, 42); }",
+  CtorArgumentY));
+  EXPECT_TRUE(matches("template  void x() { int y; (void)Y(1, y); }",
+  UnresolvedCtorArgumentY));
+  EXPECT_TRUE(matches("template  void x() { int y; (void)Y(y, 42); }",
+  UnresolvedCtorArgumentY));
   EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) y; @end "
   "void x(I* i) { int y; [i f:y]; }",
   ObjCCallArgumentY));
   EXPECT_FALSE(matchesObjC("@interface I -(void)f:(int) z; @end "
"void x(I* i) { int z; [i f:z]; }",
ObjCCallArgumentY));
   EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
+  EXPECT_TRUE(notMatches("struct Y { Y(int, int); };"
+ "void x() { int y; (void)Y(1, 2); }",
+ CtorArgumentY));
+  EXPECT_TRUE(notMatches("template "
+ "void x() { int y; (void)Y(1, 2); }",
+ UnresolvedCtorArgumentY));
 
   StatementMatcher ImplicitCastedArgument = callExpr(
 hasAnyArgument(implicitCastExpr()));
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3565,9 +3565,9 @@
 /// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12
 ///   matches [i f:12]
 AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
-  AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
-  CXXConstructExpr,
-  ObjCMessageExpr),
+  AST_POLYMORPHIC_SUPPORTED_TYPES(
+  CallExpr, CXXConstructExpr,
+  CXXUnresolvedConstructExpr, ObjCMessageExpr),
   internal::Matcher, InnerMatcher) {
   for (const Expr *Arg : Node.arguments()) {
 BoundNodesTreeBuilder Result(*Builder);
Index: include/clang/AST/ExprCXX.h
===
--- include/clang/AST/ExprCXX.h
+++ include/clang/AST/ExprCXX.h
@@ -3426,16 +3426,22 @@
   unsigned arg_size() const { return NumArgs; }
 
   using arg_iterator = Expr **;
+  using arg_range = llvm::iterator_range;
 
   arg_iterator arg_begin() { return getTrailingObjects(); }
   arg_iterator arg_end() { return arg_begin() + NumArgs; }
+  arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
 
   using const_arg_iterator = const Expr* const *;
+  using arg_const_range = llvm::iterator_range;
 
   const_arg_iterator arg_begin() const { return getTrailingObjects(); }
   const_arg_iterator arg_end() const {
 return arg_begin() + NumArgs;
   }
+  arg_const_range arguments() const {
+return arg_const_range(arg_begin(), arg_end());
+  }
 
   Expr *getArg(unsigned I) {
 assert(I < NumArgs && "Argument index out-of-range");
Index: docs/LibASTMatchersReference.html
===
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -4854,6 +4854,25 @@
 
 
 
+MatcherCXXUnresolvedConstructExpr>hasAnyArgumentMatcherExpr> InnerMatcher
+Matches any argument of a call expression or a constructor call
+expression, or an ObjC-message-send expression.
+
+Given
+  void x(int, 

[PATCH] D50605: [ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

2018-08-12 Thread Shuai Wang via Phabricator via cfe-commits
shuaiwang marked an inline comment as done.
shuaiwang added inline comments.



Comment at: include/clang/AST/ExprCXX.h:3436
   using const_arg_iterator = const Expr* const *;
+  using arg_const_range = llvm::iterator_range;
 

aaron.ballman wrote:
> Please name this `const_arg_range` for consistency.
`arg_const_range` is more widely in clang


Repository:
  rC Clang

https://reviews.llvm.org/D50605



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


[PATCH] D49722: [CStringSyntaxChecker] Check strlcat sizeof check

2018-08-12 Thread David CARLIER via Phabricator via cfe-commits
devnexen updated this revision to Diff 160272.

https://reviews.llvm.org/D49722

Files:
  lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
  test/Analysis/cstring-syntax.c

Index: test/Analysis/cstring-syntax.c
===
--- test/Analysis/cstring-syntax.c
+++ test/Analysis/cstring-syntax.c
@@ -7,6 +7,7 @@
 char  *strncat(char *, const char *, size_t);
 size_t strlen (const char *s);
 size_t strlcpy(char *, const char *, size_t);
+size_t strlcat(char *, const char *, size_t);
 
 void testStrncat(const char *src) {
   char dest[10];
@@ -33,3 +34,19 @@
   strlcpy(dest + 5, src, 5);
   strlcpy(dest + 5, src, 10); // expected-warning {{The third argument is larger than the size of the input buffer.}}
 }
+
+void testStrlcat(const char *src) {
+  char dest[10];
+  size_t badlen = 10;
+  size_t ulen;
+  strlcpy(dest, "a", sizeof("a") - 1);
+  strlcat(dest, "", (sizeof("") - 1) - sizeof(dest) - 1);
+  strlcpy(dest, "012345678", sizeof(dest));
+  strlcat(dest, "910", sizeof(dest)); // expected-warning {{The third argument allows to potentially copy more bytes than it should. Replace with the value- strlen(dest) - 1 or lower}}
+  strlcpy(dest, "0123456789", sizeof(dest));
+  strlcat(dest, "0123456789", badlen); // expected-warning {{The third argument allows to potentially copy more bytes than it should. Replace with the value 'badlen' - strlen(dest) - 1 or lower}}
+  strlcat(dest, "0123456789", badlen - strlen(dest) - 1);
+  strlcat(dest, src, ulen);
+  strlcpy(dest, src, 5);
+  strlcat(dest + 5, src, badlen); // expected-warning {{The third argument allows to potentially copy more bytes than it should. Replace with the value 'badlen' - strlen() - 1 or lower}}
+}
Index: lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
+++ lib/StaticAnalyzer/Checkers/CStringSyntaxChecker.cpp
@@ -90,7 +90,16 @@
   ///   strlcpy(dst, "abcd", 4);
   ///   strlcpy(dst + 3, "abcd", 2);
   ///   strlcpy(dst, "abcd", cpy);
-  bool containsBadStrlcpyPattern(const CallExpr *CE);
+  /// Identify erroneous patterns in the last argument to strlcat - the number
+  /// of bytes to copy.
+  /// The bad pattern checked is when the last argument is basically
+  /// pointing to the destination buffer size or argument larger or
+  /// equal to.  
+  ///   char dst[2];
+  ///   strlcat(dst, src2, sizeof(dst));
+  ///   strlcat(dst, src2, 2);
+  ///   strlcat(dst, src2, 10);
+  bool containsBadStrlcpyStrlcatPattern(const CallExpr *CE);
 
 public:
   WalkAST(const CheckerBase *Checker, BugReporter &BR, AnalysisDeclContext *AC)
@@ -142,15 +151,21 @@
   return false;
 }
 
-bool WalkAST::containsBadStrlcpyPattern(const CallExpr *CE) {
+bool WalkAST::containsBadStrlcpyStrlcatPattern(const CallExpr *CE) {
   if (CE->getNumArgs() != 3)
 return false;
+  const FunctionDecl *FD = CE->getDirectCallee();
+  bool Append = CheckerContext::isCLibraryFunction(FD, "strlcat");
   const Expr *DstArg = CE->getArg(0);
   const Expr *LenArg = CE->getArg(2);
 
   const auto *DstArgDecl = dyn_cast(DstArg->IgnoreParenImpCasts());
   const auto *LenArgDecl = dyn_cast(LenArg->IgnoreParenLValueCasts());
   uint64_t DstOff = 0;
+  // - sizeof(dst)
+  // strlcat appends at most size - strlen(dst) - 1
+  if (Append && isSizeof(LenArg, DstArg))
+return true;
   // - size_t dstlen = sizeof(dst)
   if (LenArgDecl) {
 const auto *LenArgVal = dyn_cast(LenArgDecl->getDecl());
@@ -181,7 +196,10 @@
   if (const auto *Buffer = dyn_cast(DstArgDecl->getType())) {
 ASTContext &C = BR.getContext();
 uint64_t BufferLen = C.getTypeSize(Buffer) / 8;
-if ((BufferLen - DstOff) < ILRawVal)
+auto RemainingBufferLen = BufferLen - DstOff;
+if (Append)
+  RemainingBufferLen -= 1;
+if (RemainingBufferLen < ILRawVal)
   return true;
   }
 }
@@ -220,7 +238,7 @@
  LenArg->getSourceRange());
 }
   } else if (CheckerContext::isCLibraryFunction(FD, "strlcpy")) {
-if (containsBadStrlcpyPattern(CE)) {
+if (containsBadStrlcpyStrlcatPattern(CE)) {
   const Expr *DstArg = CE->getArg(0);
   const Expr *LenArg = CE->getArg(2);
   PathDiagnosticLocation Loc =
@@ -234,6 +252,34 @@
   if (!DstName.empty())
 os << "Replace with the value 'sizeof(" << DstName << ")` or lower";
 
+  BR.EmitBasicReport(FD, Checker, "Anti-pattern in the argument",
+ "C String API", os.str(), Loc,
+ LenArg->getSourceRange());
+}
+  } else if (CheckerContext::isCLibraryFunction(FD, "strlcat")) {
+if (containsBadStrlcpyStrlcatPattern(CE)) {
+  const Expr *DstArg = CE->getArg(0);
+  const Expr *LenArg = CE->getArg(2);
+  PathDiagnosticLocation Loc =
+PathDiagnosticLocation::createBegin(LenArg, BR.getSourceManager(), A

r339527 - Renaming arg_const_range to const_arg_range; NFC.

2018-08-12 Thread Aaron Ballman via cfe-commits
Author: aaronballman
Date: Sun Aug 12 14:19:22 2018
New Revision: 339527

URL: http://llvm.org/viewvc/llvm-project?rev=339527&view=rev
Log:
Renaming arg_const_range to const_arg_range; NFC.

This form makes more sense (it is a range over constant arguments) and is most 
consistent with const_arg_iterator (there are zero instances of 
arg_const_iterator).

Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=339527&r1=339526&r2=339527&view=diff
==
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sun Aug 12 14:19:22 2018
@@ -2495,11 +2495,11 @@ public:
   typedef ExprIterator arg_iterator;
   typedef ConstExprIterator const_arg_iterator;
   typedef llvm::iterator_range arg_range;
-  typedef llvm::iterator_range arg_const_range;
+  typedef llvm::iterator_range const_arg_range;
 
   arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
-  arg_const_range arguments() const {
-return arg_const_range(arg_begin(), arg_end());
+  const_arg_range arguments() const {
+return const_arg_range(arg_begin(), arg_end());
   }
 
   arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=339527&r1=339526&r2=339527&view=diff
==
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Sun Aug 12 14:19:22 2018
@@ -1486,11 +1486,11 @@ public:
   using arg_iterator = ExprIterator;
   using const_arg_iterator = ConstExprIterator;
   using arg_range = llvm::iterator_range;
-  using arg_const_range = llvm::iterator_range;
+  using const_arg_range = llvm::iterator_range;
 
   arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
-  arg_const_range arguments() const {
-return arg_const_range(arg_begin(), arg_end());
+  const_arg_range arguments() const {
+return const_arg_range(arg_begin(), arg_end());
   }
 
   arg_iterator arg_begin() { return Args; }

Modified: cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h?rev=339527&r1=339526&r2=339527&view=diff
==
--- cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h (original)
+++ cfe/trunk/include/clang/CodeGen/CGFunctionInfo.h Sun Aug 12 14:19:22 2018
@@ -581,11 +581,11 @@ public:
   typedef ArgInfo *arg_iterator;
 
   typedef llvm::iterator_range arg_range;
-  typedef llvm::iterator_range arg_const_range;
+  typedef llvm::iterator_range const_arg_range;
 
   arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
-  arg_const_range arguments() const {
-return arg_const_range(arg_begin(), arg_end());
+  const_arg_range arguments() const {
+return const_arg_range(arg_begin(), arg_end());
   }
 
   const_arg_iterator arg_begin() const { return getArgsBuffer() + 1; }


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


[PATCH] D50605: [ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: include/clang/AST/ExprCXX.h:3436
   using const_arg_iterator = const Expr* const *;
+  using arg_const_range = llvm::iterator_range;
 

shuaiwang wrote:
> aaron.ballman wrote:
> > Please name this `const_arg_range` for consistency.
> `arg_const_range` is more widely in clang
`arg_const_range` makes no sense -- the range is of constant args, not an 
argument over a constant range. Also, it's weird to have `const_arg_iterator` 
with `arg_const_range` in the same class. I've cleaned up those few instances 
in r339527. Thanks for pointing this out!


Repository:
  rC Clang

https://reviews.llvm.org/D50605



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


[PATCH] D50605: [ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

2018-08-12 Thread Shuai Wang via Phabricator via cfe-commits
shuaiwang updated this revision to Diff 160273.
shuaiwang marked 3 inline comments as done.
shuaiwang added a comment.

arg_const_range -> const_arg_range


Repository:
  rC Clang

https://reviews.llvm.org/D50605

Files:
  docs/LibASTMatchersReference.html
  include/clang/AST/ExprCXX.h
  include/clang/ASTMatchers/ASTMatchers.h
  unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -406,16 +406,35 @@
   auto HasArgumentY = hasAnyArgument(
   ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"));
   StatementMatcher CallArgumentY = callExpr(HasArgumentY);
+  StatementMatcher CtorArgumentY = cxxConstructExpr(HasArgumentY);
+  StatementMatcher UnresolvedCtorArgumentY =
+  cxxUnresolvedConstructExpr(HasArgumentY);
   StatementMatcher ObjCCallArgumentY = objcMessageExpr(HasArgumentY);
   EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
   EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
+  EXPECT_TRUE(matches("struct Y { Y(int, int); };"
+  "void x() { int y; (void)Y(1, y); }",
+  CtorArgumentY));
+  EXPECT_TRUE(matches("struct Y { Y(int, int); };"
+  "void x() { int y; (void)Y(y, 42); }",
+  CtorArgumentY));
+  EXPECT_TRUE(matches("template  void x() { int y; (void)Y(1, y); }",
+  UnresolvedCtorArgumentY));
+  EXPECT_TRUE(matches("template  void x() { int y; (void)Y(y, 42); }",
+  UnresolvedCtorArgumentY));
   EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) y; @end "
   "void x(I* i) { int y; [i f:y]; }",
   ObjCCallArgumentY));
   EXPECT_FALSE(matchesObjC("@interface I -(void)f:(int) z; @end "
"void x(I* i) { int z; [i f:z]; }",
ObjCCallArgumentY));
   EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
+  EXPECT_TRUE(notMatches("struct Y { Y(int, int); };"
+ "void x() { int y; (void)Y(1, 2); }",
+ CtorArgumentY));
+  EXPECT_TRUE(notMatches("template "
+ "void x() { int y; (void)Y(1, 2); }",
+ UnresolvedCtorArgumentY));
 
   StatementMatcher ImplicitCastedArgument = callExpr(
 hasAnyArgument(implicitCastExpr()));
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -3565,9 +3565,9 @@
 /// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12
 ///   matches [i f:12]
 AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
-  AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
-  CXXConstructExpr,
-  ObjCMessageExpr),
+  AST_POLYMORPHIC_SUPPORTED_TYPES(
+  CallExpr, CXXConstructExpr,
+  CXXUnresolvedConstructExpr, ObjCMessageExpr),
   internal::Matcher, InnerMatcher) {
   for (const Expr *Arg : Node.arguments()) {
 BoundNodesTreeBuilder Result(*Builder);
Index: include/clang/AST/ExprCXX.h
===
--- include/clang/AST/ExprCXX.h
+++ include/clang/AST/ExprCXX.h
@@ -3426,16 +3426,22 @@
   unsigned arg_size() const { return NumArgs; }
 
   using arg_iterator = Expr **;
+  using arg_range = llvm::iterator_range;
 
   arg_iterator arg_begin() { return getTrailingObjects(); }
   arg_iterator arg_end() { return arg_begin() + NumArgs; }
+  arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
 
   using const_arg_iterator = const Expr* const *;
+  using const_arg_range = llvm::iterator_range;
 
   const_arg_iterator arg_begin() const { return getTrailingObjects(); }
   const_arg_iterator arg_end() const {
 return arg_begin() + NumArgs;
   }
+  const_arg_range arguments() const {
+return const_arg_range(arg_begin(), arg_end());
+  }
 
   Expr *getArg(unsigned I) {
 assert(I < NumArgs && "Argument index out-of-range");
Index: docs/LibASTMatchersReference.html
===
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -4854,6 +4854,25 @@
 
 
 
+MatcherCXXUnresolvedConstructExpr>hasAnyArgumentMatcherExpr> InnerMatcher
+Matches any argument of a call expression or a constructor call
+expression, or an

[PATCH] D50616: [Fixed Point Arithmetic] FixedPointCast

2018-08-12 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: ebevhan, phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch is a part of https://reviews.llvm.org/D48456 in an attempt to split 
them up. This contains the code for casting between fixed point types and other 
fixed point types.

The method for converting between fixed point types is based off the convert() 
method in APFixedPoint.


Repository:
  rC Clang

https://reviews.llvm.org/D50616

Files:
  include/clang/AST/OperationKinds.def
  include/clang/AST/Type.h
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/Type.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_conversions.c

Index: test/Frontend/fixed_point_conversions.c
===
--- /dev/null
+++ test/Frontend/fixed_point_conversions.c
@@ -0,0 +1,326 @@
+// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - | FileCheck %s -check-prefix=DEFAULT
+// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - -fpadding-on-unsigned-fixed-point | FileCheck %s -check-prefix=SAME
+
+void TestFixedPointCastSameType() {
+  _Accum a = 2.5k;
+  _Accum a2 = a;
+  // DEFAULT:  [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
+  // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a2, align 4
+
+  a2 = (_Accum)a;
+  // DEFAULT:  [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
+  // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a2, align 4
+}
+
+void TestFixedPointCastDown() {
+  long _Accum la = 2.5lk;
+  _Accum a = la;
+  // DEFAULT:  [[LACCUM:%[0-9]+]] = load i64, i64* %la, align 8
+  // DEFAULT-NEXT: [[ACCUM_AS_I64:%[0-9]+]] = ashr i64 [[LACCUM]], 16
+  // DEFAULT-NEXT: [[ACCUM:%[0-9]+]] = trunc i64 [[ACCUM_AS_I64]] to i32
+  // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+
+  a = (_Accum)la;
+  // DEFAULT:  [[LACCUM:%[0-9]+]] = load i64, i64* %la, align 8
+  // DEFAULT-NEXT: [[ACCUM_AS_I64:%[0-9]+]] = ashr i64 [[LACCUM]], 16
+  // DEFAULT-NEXT: [[ACCUM:%[0-9]+]] = trunc i64 [[ACCUM_AS_I64]] to i32
+  // DEFAULT-NEXT: store i32 [[ACCUM]], i32* %a, align 4
+
+  short _Accum sa = a;
+  // DEFAULT:  [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
+  // DEFAULT-NEXT: [[SACCUM_AS_I32:%[0-9]+]] = ashr i32 [[ACCUM]], 8
+  // DEFAULT-NEXT: [[SACCUM:%[0-9]+]] = trunc i32 [[SACCUM_AS_I32]] to i16
+  // DEFAULT-NEXT: store i16 [[SACCUM]], i16* %sa, align 2
+
+  sa = (short _Accum)a;
+  // DEFAULT:  [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
+  // DEFAULT-NEXT: [[SACCUM_AS_I32:%[0-9]+]] = ashr i32 [[ACCUM]], 8
+  // DEFAULT-NEXT: [[SACCUM:%[0-9]+]] = trunc i32 [[SACCUM_AS_I32]] to i16
+  // DEFAULT-NEXT: store i16 [[SACCUM]], i16* %sa, align 2
+}
+
+void TestFixedPointCastUp() {
+  short _Accum sa = 2.5hk;
+  _Accum a = sa;
+  // DEFAULT:  [[SACCUM:%[0-9]+]] = load i16, i16* %sa, align 2
+  // DEFAULT-NEXT: [[SACCUM_BUFF:%[0-9]+]] = sext i16 [[SACCUM]] to i24
+  // DEFAULT-NEXT: [[ACCUM:%[0-9]+]] = shl i24 [[SACCUM_BUFF]], 8
+  // DEFAULT-NEXT: [[ACCUM_EXT:%[0-9]+]] = sext i24 [[ACCUM]] to i32
+  // DEFAULT-NEXT: store i32 [[ACCUM_EXT]], i32* %a, align 4
+
+  long _Accum la = a;
+  // DEFAULT:  [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
+  // DEFAULT-NEXT: [[ACCUM_BUFF:%[0-9]+]] = sext i32 [[ACCUM]] to i48
+  // DEFAULT-NEXT: [[LACCUM:%[0-9]+]] = shl i48 [[ACCUM_BUFF]], 16
+  // DEFAULT-NEXT: [[LACCUM_EXT:%[0-9]+]] = sext i48 [[LACCUM]] to i64
+  // DEFAULT-NEXT: store i64 [[LACCUM_EXT]], i64* %la, align 8
+
+  a = (_Accum)sa;
+  // DEFAULT:  [[SACCUM:%[0-9]+]] = load i16, i16* %sa, align 2
+  // DEFAULT-NEXT: [[SACCUM_BUFF:%[0-9]+]] = sext i16 [[SACCUM]] to i24
+  // DEFAULT-NEXT: [[ACCUM:%[0-9]+]] = shl i24 [[SACCUM_BUFF]], 8
+  // DEFAULT-NEXT: [[ACCUM_EXT:%[0-9]+]] = sext i24 [[ACCUM]] to i32
+  // DEFAULT-NEXT: store i32 [[ACCUM_EXT]], i32* %a, align 4
+
+  la = (long _Accum)a;
+  // DEFAULT:  [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
+  // DEFAULT-NEXT: [[ACCUM_BUFF:%[0-9]+]] = sext i32 [[ACCUM]] to i48
+  // DEFAULT-NEXT: [[LACCUM:%[0-9]+]] = shl i48 [[ACCUM_BUFF]], 16
+  // DEFAULT-NEXT: [[LACCUM_EXT:%[0-9]+]] = sext i48 [[LACCUM]] to i64
+  // DEFAULT-NEXT: store i64 [[LACCUM_EXT]], i64* %la, align 8
+}
+
+void TestFixedPointCastSignedness() {
+  _Accum a = 2.5k;
+  unsigned _Accum ua = a;
+  // DEFAULT:  [[ACCUM:%[0-9]+]] = load i32, i32* %a, align 4
+  // DEFAULT-NEXT: [[ACCUM_EXT:%[0-9]+]] = sext i32 [[ACCUM]] to i33
+  // DEFAULT-NEXT: [[UACCUM:%[0-9]+]] = shl i33 [[ACCUM_EXT]], 1
+  // DEFAULT-NEXT: [[ACCUM_TRUNC:%[0-9]+]] = trunc i33 [[UACCUM]] to i32
+  // DEFAULT-NEXT: store i32 [[ACCUM_TRUNC]], i32* %ua, align 4
+  // SAME:  TestFixedPointCastSignedness
+  // SAME:  [[ACCUM:%[0-9]+]] = load i32, i32* %

[PATCH] D50605: [ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

2018-08-12 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

LGTM!


Repository:
  rC Clang

https://reviews.llvm.org/D50605



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


[PATCH] D50617: [ASTMatchers] Let hasObjectExpression also support UnresolvedMemberExpr, CXXDependentScopeMemberExpr

2018-08-12 Thread Shuai Wang via Phabricator via cfe-commits
shuaiwang created this revision.
shuaiwang added a reviewer: aaron.ballman.
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D50617

Files:
  docs/LibASTMatchersReference.html
  include/clang/ASTMatchers/ASTMatchers.h
  unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp


Index: unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1517,6 +1517,26 @@
 "struct X { int m; }; void f(X* x) { x->m; }",
 memberExpr(hasObjectExpression(
   hasType(pointsTo(recordDecl(hasName("X";
+  EXPECT_TRUE(matches("template  struct X { void f() { T t; t.m; } 
};",
+  cxxDependentScopeMemberExpr(hasObjectExpression(
+  declRefExpr(to(namedDecl(hasName("t";
+  EXPECT_TRUE(
+  matches("template  struct X { void f() { T t; t->m; } };",
+  cxxDependentScopeMemberExpr(hasObjectExpression(
+  declRefExpr(to(namedDecl(hasName("t";
+}
+
+TEST(HasObjectExpression, MatchesBaseOfMemberFunc) {
+  EXPECT_TRUE(matches(
+  "struct X { void f(); }; void g(X x) { x.f(); }",
+  memberExpr(hasObjectExpression(hasType(recordDecl(hasName("X")));
+  EXPECT_TRUE(matches("struct X { template  void f(); };"
+  "template  void g(X x) { x.f(); }",
+  unresolvedMemberExpr(hasObjectExpression(
+  hasType(recordDecl(hasName("X")));
+  EXPECT_TRUE(matches("template  void f(T t) { t.g(); }",
+  cxxDependentScopeMemberExpr(hasObjectExpression(
+  declRefExpr(to(namedDecl(hasName("t";
 }
 
 TEST(HasObjectExpression,
Index: include/clang/ASTMatchers/ASTMatchers.h
===
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -4806,8 +4806,11 @@
 ///   matches "x.m" and "m"
 /// with hasObjectExpression(...)
 ///   matching "x" and the implicit object expression of "m" which has type X*.
-AST_MATCHER_P(MemberExpr, hasObjectExpression,
-  internal::Matcher, InnerMatcher) {
+AST_POLYMORPHIC_MATCHER_P(
+hasObjectExpression,
+AST_POLYMORPHIC_SUPPORTED_TYPES(MemberExpr, UnresolvedMemberExpr,
+CXXDependentScopeMemberExpr),
+internal::Matcher, InnerMatcher) {
   return InnerMatcher.matches(*Node.getBase(), Finder, Builder);
 }
 
Index: docs/LibASTMatchersReference.html
===
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -4668,6 +4668,20 @@
 
 
 
+MatcherCXXDependentScopeMemberExpr>hasObjectExpressionMatcherExpr> 
InnerMatcher
+Matches a 
member expression where the object expression is
+matched by a given matcher.
+
+Given
+  struct X { int m; };
+  void f(X x) { x.m; m; }
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))
+  matches "x.m" and "m"
+with hasObjectExpression(...)
+  matching "x" and the implicit object expression of "m" which has type X*.
+
+
+
 MatcherCXXForRangeStmt>hasBodyMatcherStmt> 
InnerMatcher
 Matches a 'for', 'while', 
'do while' statement or a function
 definition that has a given body.
@@ -6673,6 +6687,20 @@
 
 
 
+MatcherUnresolvedMemberExpr>hasObjectExpressionMatcherExpr> 
InnerMatcher
+Matches a 
member expression where the object expression is
+matched by a given matcher.
+
+Given
+  struct X { int m; };
+  void f(X x) { x.m; m; }
+memberExpr(hasObjectExpression(hasType(cxxRecordDecl(hasName("X")))
+  matches "x.m" and "m"
+with hasObjectExpression(...)
+  matching "x" and the implicit object expression of "m" which has type X*.
+
+
+
 MatcherUnresolvedUsingType>hasDeclarationconst MatcherDecl>  
InnerMatcher
 Matches a node if 
the declaration associated with that node
 matches the given matcher.


Index: unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
===
--- unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1517,6 +1517,26 @@
 "struct X { int m; }; void f(X* x) { x->m; }",
 memberExpr(hasObjectExpression(
   hasType(pointsTo(recordDecl(hasName("X";
+  E

r339530 - [ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

2018-08-12 Thread Shuai Wang via cfe-commits
Author: shuaiwang
Date: Sun Aug 12 16:30:05 2018
New Revision: 339530

URL: http://llvm.org/viewvc/llvm-project?rev=339530&view=rev
Log:
[ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

Subscribers: cfe-commits

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

Modified:
cfe/trunk/docs/LibASTMatchersReference.html
cfe/trunk/include/clang/AST/ExprCXX.h
cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Modified: cfe/trunk/docs/LibASTMatchersReference.html
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=339530&r1=339529&r2=339530&view=diff
==
--- cfe/trunk/docs/LibASTMatchersReference.html (original)
+++ cfe/trunk/docs/LibASTMatchersReference.html Sun Aug 12 16:30:05 2018
@@ -4854,6 +4854,25 @@ match Base.
 
 
 
+MatcherCXXUnresolvedConstructExpr>hasAnyArgumentMatcherExpr> 
InnerMatcher
+Matches any argument 
of a call expression or a constructor call
+expression, or an ObjC-message-send expression.
+
+Given
+  void x(int, int, int) { int y; x(1, y, 42); }
+callExpr(hasAnyArgument(declRefExpr()))
+  matches x(1, y, 42)
+with hasAnyArgument(...)
+  matching y
+
+For ObjectiveC, given
+  @interface I - (void) f:(int) y; @end
+  void foo(I *i) { [i f:12]; }
+objcMessageExpr(hasAnyArgument(integerLiteral(equals(12
+  matches [i f:12]
+
+
+
 MatcherCallExpr>calleeMatcherDecl> 
InnerMatcher
 Matches if the call 
expression's callee's declaration matches the
 given matcher.
@@ -5938,8 +5957,8 @@ nestedNameSpecifier(specifiesType(
 
 
 
-MatcherObjCMessageExpr>hasAnyArgumentMatcherExpr> 
InnerMatcher
-Matches any argument 
of a call expression or a constructor call
+MatcherObjCMessageExpr>hasAnyArgumentMatcherExpr> 
InnerMatcher
+Matches any argument 
of a call expression or a constructor call
 expression, or an ObjC-message-send expression.
 
 Given

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=339530&r1=339529&r2=339530&view=diff
==
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Sun Aug 12 16:30:05 2018
@@ -3426,16 +3426,22 @@ public:
   unsigned arg_size() const { return NumArgs; }
 
   using arg_iterator = Expr **;
+  using arg_range = llvm::iterator_range;
 
   arg_iterator arg_begin() { return getTrailingObjects(); }
   arg_iterator arg_end() { return arg_begin() + NumArgs; }
+  arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
 
   using const_arg_iterator = const Expr* const *;
+  using const_arg_range = llvm::iterator_range;
 
   const_arg_iterator arg_begin() const { return getTrailingObjects(); }
   const_arg_iterator arg_end() const {
 return arg_begin() + NumArgs;
   }
+  const_arg_range arguments() const {
+return const_arg_range(arg_begin(), arg_end());
+  }
 
   Expr *getArg(unsigned I) {
 assert(I < NumArgs && "Argument index out-of-range");

Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=339530&r1=339529&r2=339530&view=diff
==
--- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Sun Aug 12 16:30:05 2018
@@ -3565,9 +3565,9 @@ AST_MATCHER(CXXCtorInitializer, isMember
 /// objcMessageExpr(hasAnyArgument(integerLiteral(equals(12
 ///   matches [i f:12]
 AST_POLYMORPHIC_MATCHER_P(hasAnyArgument,
-  AST_POLYMORPHIC_SUPPORTED_TYPES(CallExpr,
-  CXXConstructExpr,
-  ObjCMessageExpr),
+  AST_POLYMORPHIC_SUPPORTED_TYPES(
+  CallExpr, CXXConstructExpr,
+  CXXUnresolvedConstructExpr, ObjCMessageExpr),
   internal::Matcher, InnerMatcher) {
   for (const Expr *Arg : Node.arguments()) {
 BoundNodesTreeBuilder Result(*Builder);

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatche

[PATCH] D50605: [ASTMatchers] Let hasAnyArgument also support CXXUnresolvedConstructExpr

2018-08-12 Thread Shuai Wang via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rL339530: [ASTMatchers] Let hasAnyArgument also support 
CXXUnresolvedConstructExpr (authored by shuaiwang, committed by ).
Herald added a subscriber: llvm-commits.

Repository:
  rL LLVM

https://reviews.llvm.org/D50605

Files:
  cfe/trunk/docs/LibASTMatchersReference.html
  cfe/trunk/include/clang/AST/ExprCXX.h
  cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
  cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp

Index: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
===
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -406,16 +406,35 @@
   auto HasArgumentY = hasAnyArgument(
   ignoringParenImpCasts(declRefExpr(to(varDecl(hasName("y"));
   StatementMatcher CallArgumentY = callExpr(HasArgumentY);
+  StatementMatcher CtorArgumentY = cxxConstructExpr(HasArgumentY);
+  StatementMatcher UnresolvedCtorArgumentY =
+  cxxUnresolvedConstructExpr(HasArgumentY);
   StatementMatcher ObjCCallArgumentY = objcMessageExpr(HasArgumentY);
   EXPECT_TRUE(matches("void x(int, int) { int y; x(1, y); }", CallArgumentY));
   EXPECT_TRUE(matches("void x(int, int) { int y; x(y, 42); }", CallArgumentY));
+  EXPECT_TRUE(matches("struct Y { Y(int, int); };"
+  "void x() { int y; (void)Y(1, y); }",
+  CtorArgumentY));
+  EXPECT_TRUE(matches("struct Y { Y(int, int); };"
+  "void x() { int y; (void)Y(y, 42); }",
+  CtorArgumentY));
+  EXPECT_TRUE(matches("template  void x() { int y; (void)Y(1, y); }",
+  UnresolvedCtorArgumentY));
+  EXPECT_TRUE(matches("template  void x() { int y; (void)Y(y, 42); }",
+  UnresolvedCtorArgumentY));
   EXPECT_TRUE(matchesObjC("@interface I -(void)f:(int) y; @end "
   "void x(I* i) { int y; [i f:y]; }",
   ObjCCallArgumentY));
   EXPECT_FALSE(matchesObjC("@interface I -(void)f:(int) z; @end "
"void x(I* i) { int z; [i f:z]; }",
ObjCCallArgumentY));
   EXPECT_TRUE(notMatches("void x(int, int) { x(1, 2); }", CallArgumentY));
+  EXPECT_TRUE(notMatches("struct Y { Y(int, int); };"
+ "void x() { int y; (void)Y(1, 2); }",
+ CtorArgumentY));
+  EXPECT_TRUE(notMatches("template "
+ "void x() { int y; (void)Y(1, 2); }",
+ UnresolvedCtorArgumentY));
 
   StatementMatcher ImplicitCastedArgument = callExpr(
 hasAnyArgument(implicitCastExpr()));
Index: cfe/trunk/docs/LibASTMatchersReference.html
===
--- cfe/trunk/docs/LibASTMatchersReference.html
+++ cfe/trunk/docs/LibASTMatchersReference.html
@@ -4854,6 +4854,25 @@
 
 
 
+MatcherCXXUnresolvedConstructExpr>hasAnyArgumentMatcherExpr> InnerMatcher
+Matches any argument of a call expression or a constructor call
+expression, or an ObjC-message-send expression.
+
+Given
+  void x(int, int, int) { int y; x(1, y, 42); }
+callExpr(hasAnyArgument(declRefExpr()))
+  matches x(1, y, 42)
+with hasAnyArgument(...)
+  matching y
+
+For ObjectiveC, given
+  @interface I - (void) f:(int) y; @end
+  void foo(I *i) { [i f:12]; }
+objcMessageExpr(hasAnyArgument(integerLiteral(equals(12
+  matches [i f:12]
+
+
+
 MatcherCallExpr>calleeMatcherDecl> InnerMatcher
 Matches if the call expression's callee's declaration matches the
 given matcher.
@@ -5938,8 +5957,8 @@
 
 
 
-MatcherObjCMessageExpr>hasAnyArgumentMatcherExpr> InnerMatcher
-Matches any argument of a call expression or a constructor call
+MatcherObjCMessageExpr>hasAnyArgumentMatcherExpr> InnerMatcher
+Matches any argument of a call expression or a constructor call
 expression, or an ObjC-message-send expression.
 
 Given
Index: cfe/trunk/include/clang/AST/ExprCXX.h
===
--- cfe/trunk/include/clang/AST/ExprCXX.h
+++ cfe/trunk/include/clang/AST/ExprCXX.h
@@ -3426,16 +3426,22 @@
   unsigned arg_size() const { return NumArgs; }
 
   using arg_iterator = Expr **;
+  using arg_range = llvm::iterator_range;
 
   arg_iterator arg_begin() { return getTrailingObjects(); }
   arg_iterator arg_end() { return arg_begin() + NumAr

[PATCH] D50618: Refactor Darwin driver to refer to runtimes by component

2018-08-12 Thread Chris Bieneman via Phabricator via cfe-commits
beanz created this revision.
beanz added reviewers: phosek, bruno, arphaman.

In r335809, Petr Hosek lays out support for what he calls the multiarch
runtimes layout. This new way of laying out the directories for runtime
libraries is workable for all platforms. Petr did some of the common
infrastructure and made it work for Linux and Fuscia. This patch is a
cleanup to the Darwin and MachO drivers to serve as a step toward
supporting it in Darwin.

This patch does primarily two things:
(1) Changes the APIs for how the Darwin driver refers to compiler-rt
libraries to use the component names, similar to how Linux and Fuscia do

(2) Removes some legacy functionality for supporting macOS versions
before 10.6. This functionality is effectively dead code because in
r339277, the support was removed from compiler-rt for generating the 10.4
runtime support library, and Xcode 10 (currently in beta) removes
libgcc_s.10.4 and libgcc_s.10.5 from the macOS SDK.

With this patch landed a subsequent patch can modify
MachO::AddLinkRuntimeLib to support the multiarch runtimes layout.

Worth noting: None of the removed functionality was actually covered in
the test suite. So no test case updates are required.


Repository:
  rC Clang

https://reviews.llvm.org/D50618

Files:
  lib/Driver/ToolChains/Darwin.cpp
  lib/Driver/ToolChains/Darwin.h

Index: lib/Driver/ToolChains/Darwin.h
===
--- lib/Driver/ToolChains/Darwin.h
+++ lib/Driver/ToolChains/Darwin.h
@@ -189,9 +189,9 @@
 
   /// Add a runtime library to the list of items to link.
   void AddLinkRuntimeLib(const llvm::opt::ArgList &Args,
- llvm::opt::ArgStringList &CmdArgs,
- StringRef DarwinLibName,
- RuntimeLinkOptions Opts = RuntimeLinkOptions()) const;
+ llvm::opt::ArgStringList &CmdArgs, StringRef Component,
+ RuntimeLinkOptions Opts = RuntimeLinkOptions(),
+ bool IsShared = false) const;
 
   /// Add any profiling runtime libraries that are needed. This is essentially a
   /// MachO specific version of addProfileRT in Tools.cpp.
@@ -252,6 +252,8 @@
 return llvm::ExceptionHandling::None;
   }
 
+  virtual StringRef getOSLibraryNameSuffix() const { return ""; }
+
   /// }
 };
 
@@ -418,7 +420,7 @@
  Action::OffloadKind DeviceOffloadKind) const override;
 
   StringRef getPlatformFamily() const;
-  StringRef getOSLibraryNameSuffix() const;
+  StringRef getOSLibraryNameSuffix() const override;
 
 public:
   static StringRef getSDKName(StringRef isysroot);
Index: lib/Driver/ToolChains/Darwin.cpp
===
--- lib/Driver/ToolChains/Darwin.cpp
+++ lib/Driver/ToolChains/Darwin.cpp
@@ -513,8 +513,7 @@
   // These libraries should be linked first, to make sure the
   // __safestack_init constructor executes before everything else
   if (getToolChain().getSanitizerArgs().needsSafeStackRt()) {
-getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs,
-  "libclang_rt.safestack_osx.a",
+getMachOToolChain().AddLinkRuntimeLib(Args, CmdArgs, "safestack",
   toolchains::Darwin::RLO_AlwaysLink);
   }
 
@@ -917,8 +916,17 @@
 }
 
 void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
-  StringRef DarwinLibName,
-  RuntimeLinkOptions Opts) const {
+  StringRef Component, RuntimeLinkOptions Opts,
+  bool IsShared) const {
+  SmallString<64> DarwinLibName = StringRef("libclang_rt.");
+  // an Darwin the builtins compomnent is not in the library name
+  if (Component != "builtins") {
+DarwinLibName += Component;
+if (!(Opts & RLO_IsEmbedded))
+  DarwinLibName += "_";
+  }
+  DarwinLibName += getOSLibraryNameSuffix();
+  DarwinLibName += IsShared ? "_dynamic.dylib" : ".a";
   SmallString<128> Dir(getDriver().ResourceDir);
   llvm::sys::path::append(
   Dir, "lib", (Opts & RLO_IsEmbedded) ? "macho_embedded" : "darwin");
@@ -1022,10 +1030,8 @@
   ArgStringList &CmdArgs) const {
   if (!needsProfileRT(Args)) return;
 
-  AddLinkRuntimeLib(
-  Args, CmdArgs,
-  (Twine("libclang_rt.profile_") + getOSLibraryNameSuffix() + ".a").str(),
-  RuntimeLinkOptions(RLO_AlwaysLink | RLO_FirstLink));
+  AddLinkRuntimeLib(Args, CmdArgs, "profile",
+RuntimeLinkOptions(RLO_AlwaysLink | RLO_FirstLink));
 
   // If we have a symbol export directive and we're linking in the profile
   // runtime, automatically export symbols necessary to implement some of the
@@ -1042,12 +1048,7 @@
   StringRef Sanitizer,
   bool Shared) const {
   auto RLO = RuntimeLinkOptio

[PATCH] D50619: [clang-tidy] Handle unresolved expressions in ExprMutationAnalyzer

2018-08-12 Thread Shuai Wang via Phabricator via cfe-commits
shuaiwang created this revision.
shuaiwang added reviewers: aaron.ballman, JonasToth.
Herald added subscribers: cfe-commits, a.sidorin, xazax.hun.
Herald added a reviewer: george.karpenkov.

- If a function is unresolved, assume it mutates its arguments
- Follow unresolved member expressions for nested mutations


Repository:
  rCTE Clang Tools Extra

https://reviews.llvm.org/D50619

Files:
  clang-tidy/utils/ExprMutationAnalyzer.cpp
  unittests/clang-tidy/ExprMutationAnalyzerTest.cpp

Index: unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
===
--- unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
+++ unittests/clang-tidy/ExprMutationAnalyzerTest.cpp
@@ -114,6 +114,20 @@
   EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()"));
 }
 
+TEST(ExprMutationAnalyzerTest, AssumedNonConstMemberFunc) {
+  auto AST = tooling::buildASTFromCode(
+  "struct X { template  void mf(); };"
+  "template  void f() { X x; x.mf(); }");
+  auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()"));
+
+  AST =
+  tooling::buildASTFromCode("template  void f() { T x; x.mf(); }");
+  Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.mf()"));
+}
+
 TEST(ExprMutationAnalyzerTest, ConstMemberFunc) {
   const auto AST = tooling::buildASTFromCode(
   "void f() { struct Foo { void mf() const; }; Foo x; x.mf(); }");
@@ -292,6 +306,24 @@
   ElementsAre("std::forward(x)"));
 }
 
+TEST(ExprMutationAnalyzerTest, CallUnresolved) {
+  auto AST =
+  tooling::buildASTFromCode("template  void f() { T x; g(x); }");
+  auto Results =
+  match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(x)"));
+
+  AST = tooling::buildASTFromCode(
+  "template  void f() { int x; g(T(), x); }");
+  Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("g(T(), x)"));
+
+  AST = tooling::buildASTFromCode(
+  "template  void f() { int x; (void)T(x); }");
+  Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("T(x)"));
+}
+
 TEST(ExprMutationAnalyzerTest, ReturnAsValue) {
   const auto AST = tooling::buildASTFromCode("int f() { int x; return x; }");
   const auto Results =
@@ -398,21 +430,31 @@
 }
 
 TEST(ExprMutationAnalyzerTest, NestedMemberModified) {
-  const auto AST = tooling::buildASTFromCode(
+  auto AST = tooling::buildASTFromCode(
   "void f() { struct A { int vi; }; struct B { A va; }; "
   "struct C { B vb; }; C x; x.vb.va.vi = 10; }");
-  const auto Results =
+  auto Results =
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.vb.va.vi = 10"));
+
+  AST = tooling::buildASTFromCode(
+  "template  void f() { T x; x.y.z = 10; }");
+  Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_THAT(mutatedBy(Results, AST.get()), ElementsAre("x.y.z = 10"));
 }
 
 TEST(ExprMutationAnalyzerTest, NestedMemberNotModified) {
-  const auto AST = tooling::buildASTFromCode(
+  auto AST = tooling::buildASTFromCode(
   "void f() { struct A { int vi; }; struct B { A va; }; "
   "struct C { B vb; }; C x; x.vb.va.vi; }");
-  const auto Results =
+  auto Results =
   match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
   EXPECT_FALSE(isMutated(Results, AST.get()));
+
+  AST =
+  tooling::buildASTFromCode("template  void f() { T x; x.y.z; }");
+  Results = match(withEnclosingCompound(declRefTo("x")), AST->getASTContext());
+  EXPECT_FALSE(isMutated(Results, AST.get()));
 }
 
 TEST(ExprMutationAnalyzerTest, CastToValue) {
Index: clang-tidy/utils/ExprMutationAnalyzer.cpp
===
--- clang-tidy/utils/ExprMutationAnalyzer.cpp
+++ clang-tidy/utils/ExprMutationAnalyzer.cpp
@@ -145,11 +145,16 @@
 hasUnaryOperand(equalsNode(Exp)));
 
   // Invoking non-const member function.
+  // A member function is assumed to be non-const when it is unresolved.
   const auto NonConstMethod = cxxMethodDecl(unless(isConst()));
   const auto AsNonConstThis =
   expr(anyOf(cxxMemberCallExpr(callee(NonConstMethod), on(equalsNode(Exp))),
  cxxOperatorCallExpr(callee(NonConstMethod),
- hasArgument(0, equalsNode(Exp);
+ hasArgument(0, equalsNode(Exp))),
+ callExpr(callee(expr(anyOf(
+ unresolvedMemberExpr(hasObjectExpression(equalsNode(Exp))),
+ cxxDependentScopeMemberExpr(
+

[PATCH] D21767: Fix instantiation of friend function templates

2018-08-12 Thread Serge Pavlov via Phabricator via cfe-commits
sepavloff updated this revision to Diff 160290.
sepavloff added a comment.

Rebased the patch, it is still actual.


Repository:
  rC Clang

https://reviews.llvm.org/D21767

Files:
  include/clang/AST/ASTLambda.h
  include/clang/AST/Decl.h
  include/clang/Sema/Sema.h
  lib/AST/Decl.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/SemaTemplateInstantiateDecl.cpp
  test/SemaTemplate/instantiate-friend-function.cpp

Index: test/SemaTemplate/instantiate-friend-function.cpp
===
--- test/SemaTemplate/instantiate-friend-function.cpp
+++ test/SemaTemplate/instantiate-friend-function.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-// RUN: %clang_cc1 -S -triple %itanium_abi_triple -std=c++11 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -fcxx-exceptions %s
+// RUN: %clang_cc1 -S -triple %itanium_abi_triple -std=c++11 -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s
 // expected-no-diagnostics
 
 namespace PR10856 {
@@ -47,3 +47,572 @@
 
 // bool PR10856_Root::g, void>(PR10856_Root::MyClass)
 // CHECK: call {{.*}} @_ZN12PR10856_Root1gINS_7MyClassIiEEvEEbT_
+
+// Instantiate friend function, pattern is at file level.
+
+
+template struct C01 {
+  template friend void func_01(C01 &, T1);
+  template friend void func_01a(C01 &, T2);
+};
+
+C01 c01;
+
+void f_01() {
+  func_01(c01, 0.0);
+  func_01a(c01, 0.0);
+}
+
+template void func_01(C01 &, T1) {}
+template void func_01a(C01 &, T2) {}
+
+// void func_01(C01&, double)
+// CHECK: define linkonce_odr void @_Z7func_01IdEvR3C01IiET_
+//
+// void func_01a(C01&, double)
+// CHECK: define linkonce_odr void @_Z8func_01aIidEvR3C01IT_ET0_
+
+
+template struct C02 {
+  template friend void func_02(const C02 &, T1) { T var; }
+  template friend void func_02a(const C02 &, T2) { T var; }
+  template friend constexpr unsigned func_02b(const C02 &, const T1 x) { return sizeof(T1); }
+};
+
+const C02 c02;
+
+void f_02() {
+  func_02(c02, 0.0);
+  func_02a(c02, 0.0);
+  static_assert(func_02b(c02, short(122)) == sizeof(short), "Invalid calculation");
+  static_assert(func_02b(c02, 122L) == sizeof(long), "Invalid calculation");
+}
+
+// void func_02(C02 const&, double)
+// CHECK: define linkonce_odr void @_Z7func_02IdEvRK3C02IiET_
+//
+// void func_02a(C02 const&, double)
+// CHECK: define linkonce_odr void @_Z8func_02aIidEvRK3C02IT_ET0_
+
+
+template struct C03 {
+  template friend void func_03(C03 &, T1);
+  template friend void func_03a(C03 &, T2);
+};
+
+C03 c03;
+
+void f_03() {
+  func_03(c03, 0.0);
+  func_03a(c03, 0.0);
+}
+
+template struct C03A {
+  template friend void func_03(C03 &, T1) { }
+};
+template struct C03B {
+  template friend void func_03a(C03 &, T2) { T var; }
+};
+
+C03A c03a;
+C03B c03b;
+
+// void func_03(C03&, double)
+// CHECK: define linkonce_odr void @_Z7func_03IdEvR3C03IiET_
+//
+// void func_03a(C03&, double)
+// CHECK: define linkonce_odr void @_Z8func_03aIidEvR3C03IT_ET0_
+
+
+// File level declaration, friend pattern.
+
+
+template void func_10(T1 *x);
+template void func_10a(T1 *x, T2 *y);
+template constexpr unsigned func_10b(const T1 x);
+template constexpr unsigned func_10c(const T1 x);
+
+template
+struct C10 {
+  template friend void func_10(T1 *x) { T var; }
+  template friend void func_10a(T1 *x, T2 *y) { T var; }
+  template friend constexpr unsigned func_10b(const T1 x) { return sizeof(T1); }
+  template friend constexpr unsigned func_10c(const T1 x) { return sizeof(T); }
+};
+
+C10 v10;
+
+void use_10(int *x) {
+  func_10(x);
+  func_10a(x, &x);
+  static_assert(func_10b(short(122)) == sizeof(short), "Invalid calculation");
+  static_assert(func_10b(122L) == sizeof(long), "Invalid calculation");
+  static_assert(func_10c(short(122)) == sizeof(int), "Invalid calculation");
+  static_assert(func_10c(122L) == sizeof(int), "Invalid calculation");
+}
+
+// void func_10(int*)
+// CHECK: define linkonce_odr void @_Z7func_10IiEvPT_
+//
+// void func_10a(int*, int**)
+// CHECK: define linkonce_odr void @_Z8func_10aIiPiEvPT_PT0_
+
+
+template
+struct C11 {
+  template friend void func_11(T1 *x) { T var; }
+  template friend void func_11a(T1 *x, T2 *y) { T var; }
+  template friend constexpr unsigned func_11b(const T1 x) { return sizeof(T1); }
+  template friend constexpr unsigned func_11c(const T1 x) { return sizeof(T); }
+};
+
+C11 v11;
+
+template void func_11(T *x);
+template void func_11a(T1 *x, T2 *y);
+template constexpr unsigned func_11b(const T1 x);
+template constexpr unsigned func_11c(const T1 x);
+
+void use_11(int *x) {
+  func_11(x);
+  func_11a(x, &x);
+  static_assert(func_11b(short(123)) == sizeof(short), "Invalid calculation");
+  static_assert(func_11b(123L) == sizeof(long), "Invalid calculation");
+  static_assert(func_11c(short(123)) == sizeof(int), "Invalid calculation");
+  static_assert(func_11c(123L) == sizeof(int), "Invalid calculation");
+}
+
+// void func_11(int*)
+// CHECK: define lin