Re: [PATCH] D21962: MPITypeMismatchCheck for Clang-Tidy

2016-07-23 Thread Alexander Kornienko via cfe-commits
alexfh accepted this revision.
alexfh added a comment.
This revision is now accepted and ready to land.

Looks good with one comment.



Comment at: clang-tidy/mpi/TypeMismatchCheck.cpp:237
@@ +236,3 @@
+void TypeMismatchCheck::check(const MatchFinder::MatchResult &Result) {
+  static ento::mpi::MPIFunctionClassifier FuncClassifier{*Result.Context};
+  const CallExpr *const CE = Result.Nodes.getNodeAs("CE");

Use parentheses syntax for initialization.
http://llvm.org/docs/CodingStandards.html#do-not-use-braced-initializer-lists-to-call-a-constructor


https://reviews.llvm.org/D21962



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


Re: [PATCH] D22208: [clang-tidy] Fixes to modernize-use-emplace

2016-07-23 Thread Alexander Kornienko via cfe-commits
alexfh added a comment.

In https://reviews.llvm.org/D22208#492385, @Prazek wrote:

> There is one bug left:
>
> In the ClangIncludeFixer.cpp:169 there is push back that looks like this
>
> Symbols.push_back(find_all_symbols::SymbolInfo(
>
>   Split.first.trim(),
>   find_all_symbols::SymbolInfo::SymbolKind::Unknown,
>   CommaSplits[I].trim(), 1, {}, /*NumOccurrences=*/E - I));
>   
>
> There is initializer list inside that should not allow this to be matched 
> (because I check for initializer list as argument)
>
> Unfortunatelly clang AST doesn't mention any initializer list.


I guess, `CXXConstructExpr::isListInitialization()` is what you need to check 
here.


Repository:
  rL LLVM

https://reviews.llvm.org/D22208



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


Re: [PATCH] D22656: [Clang-apply-replacements] Remove custom version printing; fix some Include What You Use warnings

2016-07-23 Thread Alexander Kornienko via cfe-commits
alexfh added a comment.

In https://reviews.llvm.org/D22656#493036, @Eugene.Zelenko wrote:

> Don't include DiagnosticIDs.h.


This header is just an example. I don't want anyone (including myself) manually 
figure out which of the headers inserted by IWYU actually need to be inserted. 
I'm also against adding #includes for every single transitively included 
header, since many of the headers can be considered "exported" by other 
headers. So, please, stop sending IWYU cleanups before reaching the general 
agreement and properly annotating LLVM and Clang headers.


Repository:
  rL LLVM

https://reviews.llvm.org/D22656



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


[PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Jonas Devlieghere via cfe-commits
JDevlieghere created this revision.
JDevlieghere added a reviewer: alexfh.
JDevlieghere added a subscriber: cfe-commits.
JDevlieghere added a project: clang-tools-extra.

This check emits a warning when memcpy is used and suggest replacing it with a 
call to std::copy. 

Using std::copy opens up the possibility of type-aware optimizations which are 
not possible with memcpy.  

Taken from: https://llvm.org/bugs/show_bug.cgi?id=22209 

https://reviews.llvm.org/D22725

Files:
  clang-tidy/misc/CMakeLists.txt
  clang-tidy/misc/MiscTidyModule.cpp
  clang-tidy/misc/ReplaceMemcpyCheck.cpp
  clang-tidy/misc/ReplaceMemcpyCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/misc-replace-memcpy.rst
  test/clang-tidy/misc-replace-memcpy.cpp

Index: test/clang-tidy/misc-replace-memcpy.cpp
===
--- /dev/null
+++ test/clang-tidy/misc-replace-memcpy.cpp
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s misc-replace-memcpy %t
+
+#include 
+#include 
+#include 
+
+void f() {
+  char foo[] = "foo", bar[3], baz[3];
+  std::memcpy(bar, foo, sizeof bar);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Use std::copy instead of memcyp [misc-replace-memcpy]
+  // CHECK-FIXES: std::copy(foo, (foo) + (sizeof bar), bar);
+
+  bool b = false;
+  std::memcpy(baz, b ? foo : bar, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Use std::copy instead of memcyp [misc-replace-memcpy]
+  // CHECK-FIXES: std::copy(b ? foo : bar, (b ? foo : bar) + (3), baz);
+
+  memcpy(bar, foo, sizeof bar);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Use std::copy instead of memcyp [misc-replace-memcpy]
+  // CHECK-FIXES: std::copy(foo, (foo) + (sizeof bar), bar);
+
+  std::copy(foo, foo + sizeof bar, bar);
+}
Index: docs/clang-tidy/checks/misc-replace-memcpy.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/misc-replace-memcpy.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - misc-replace-memcpy
+
+misc-replace-memcpy
+===
+
+Replaces ``memcpy`` with ``std::copy``. This allows the compiler to decide on
+the most performant implementationon. Parenthesis are added devensively to
+preclude the summation from taking precedence.
+
+Example:
+
+.. code:: c++
+
+std::memcpy(dest, source, sizeof dest);
+
+// transforms to:
+
+std::copy(source, (source) + (sizeof dest), dest);
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -29,6 +29,7 @@
cppcoreguidelines-pro-type-static-cast-downcast
cppcoreguidelines-pro-type-union-access
cppcoreguidelines-pro-type-vararg
+   cppcoreguidelines-slicing
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
@@ -72,6 +73,7 @@
misc-non-copyable-objects
misc-pointer-and-integral-operation
misc-redundant-expression
+   misc-replace-memcpy
misc-sizeof-container
misc-sizeof-expression
misc-static-assert
Index: clang-tidy/misc/ReplaceMemcpyCheck.h
===
--- /dev/null
+++ clang-tidy/misc/ReplaceMemcpyCheck.h
@@ -0,0 +1,38 @@
+//===--- ReplaceMemcpyCheck.h - clang-tidy---*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_REPLACE_MEMCPY_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_REPLACE_MEMCPY_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// Replaces memcpy with std::copy
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-replace-memcpy.html
+class ReplaceMemcpyCheck : public ClangTidyCheck {
+public:
+  ReplaceMemcpyCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+  static StringRef GetText(const Expr *Expression, const SourceManager &SM,
+   const LangOptions &LangOpts);
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_REPLACE_MEMCPY_H
Index: clang-tidy/misc/ReplaceMemcpyCheck.cpp
===
--- /dev/null
+++ clang-tidy/misc/ReplaceMemcpyCheck.cpp
@@ -0,0 +1,60 @@
+//===--- ReplaceMemcpyCheck.cpp - clang-tidy---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illino

Re: [PATCH] D21962: MPITypeMismatchCheck for Clang-Tidy

2016-07-23 Thread Alexander Droste via cfe-commits
Alexander_Droste updated this revision to Diff 65222.
Alexander_Droste marked an inline comment as done.
Alexander_Droste added a comment.

- use parentheses instead of braces


https://reviews.llvm.org/D21962

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/mpi/CMakeLists.txt
  clang-tidy/mpi/MPITidyModule.cpp
  clang-tidy/mpi/TypeMismatchCheck.cpp
  clang-tidy/mpi/TypeMismatchCheck.h
  clang-tidy/plugin/CMakeLists.txt
  clang-tidy/tool/CMakeLists.txt
  clang-tidy/tool/ClangTidyMain.cpp
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/mpi-type-mismatch.rst
  test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
  test/clang-tidy/mpi-type-mismatch.cpp

Index: test/clang-tidy/mpi-type-mismatch.cpp
===
--- /dev/null
+++ test/clang-tidy/mpi-type-mismatch.cpp
@@ -0,0 +1,254 @@
+// RUN: %check_clang_tidy %s mpi-type-mismatch %t -- -- -I %S/Inputs/mpi-type-mismatch
+
+#include "mpimock.h"
+
+void charNegativeTest() {
+  unsigned char buf;
+  MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned char' does not match the MPI datatype 'MPI_CHAR' [mpi-type-mismatch]
+  
+  int buf2;
+  MPI_Send(&buf2, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'int' does not match the MPI datatype 'MPI_CHAR'
+  
+  short buf3;
+  MPI_Send(&buf3, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'short' does not match the MPI datatype 'MPI_CHAR'
+
+  long buf4;
+  MPI_Send(&buf4, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'long' does not match the MPI datatype 'MPI_CHAR'
+  
+  int8_t buf5;
+  MPI_Send(&buf5, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'int8_t' does not match the MPI datatype 'MPI_CHAR'
+
+  uint16_t buf6;
+  MPI_Send(&buf6, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint16_t' does not match the MPI datatype 'MPI_CHAR'
+
+  long double _Complex buf7;
+  MPI_Send(&buf7, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'long double _Complex' does not match the MPI datatype 'MPI_CHAR'
+
+  std::complex buf8;
+  MPI_Send(&buf8, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'complex' does not match the MPI datatype 'MPI_CHAR'
+}
+
+void intNegativeTest() {
+  unsigned char buf;
+  MPI_Send(&buf, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned char' does not match the MPI datatype 'MPI_INT'
+  
+  unsigned buf2;
+  MPI_Send(&buf2, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned int' does not match the MPI datatype 'MPI_INT'
+  
+  short buf3;
+  MPI_Send(&buf3, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'short' does not match the MPI datatype 'MPI_INT'
+
+  long buf4;
+  MPI_Send(&buf4, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'long' does not match the MPI datatype 'MPI_INT'
+  
+  int8_t buf5;
+  MPI_Send(&buf5, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'int8_t' does not match the MPI datatype 'MPI_INT'
+
+  uint16_t buf6;
+  MPI_Send(&buf6, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'uint16_t' does not match the MPI datatype 'MPI_INT'
+
+  long double _Complex buf7;
+  MPI_Send(&buf7, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'long double _Complex' does not match the MPI datatype 'MPI_INT'
+
+  std::complex buf8;
+  MPI_Send(&buf8, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'complex' does not match the MPI datatype 'MPI_INT'
+}
+
+void longNegativeTest() {
+  char buf;
+  MPI_Send(&buf, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'char' does not match the MPI datatype 'MPI_LONG'
+  
+  unsigned buf2;
+  MPI_Send(&buf2, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned int' does not match the MPI datatype 'MPI_LONG'
+  
+  unsigned short buf3;
+  MPI_Send(&buf3, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned short' does not match the MPI datatype 'MPI_LONG'
+
+  unsigned long buf4;
+  MPI_Send(&buf4, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer type 'unsigned long' does not match the MPI datatype 'MPI_LONG'
+  
+  int8_t buf5;
+  MPI_Send(&buf5, 1, MPI_LONG, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@L

Re: [PATCH] D22622: [analyzer] Add more info to exploded graph dumps

2016-07-23 Thread Artem Dergachev via cfe-commits
NoQ updated this revision to Diff 65223.

https://reviews.llvm.org/D22622

Files:
  lib/StaticAnalyzer/Core/ExprEngine.cpp

Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -2521,26 +2521,10 @@
   // FIXME: Since we do not cache error nodes in ExprEngine now, this does not
   // work.
   static std::string getNodeAttributes(const ExplodedNode *N, void*) {
-
-#if 0
-  // FIXME: Replace with a general scheme to tell if the node is
-  // an error node.
-if (GraphPrintCheckerState->isImplicitNullDeref(N) ||
-GraphPrintCheckerState->isExplicitNullDeref(N) ||
-GraphPrintCheckerState->isUndefDeref(N) ||
-GraphPrintCheckerState->isUndefStore(N) ||
-GraphPrintCheckerState->isUndefControlFlow(N) ||
-GraphPrintCheckerState->isUndefResult(N) ||
-GraphPrintCheckerState->isBadCall(N) ||
-GraphPrintCheckerState->isUndefArg(N))
-  return "color=\"red\",style=\"filled\"";
-
-if (GraphPrintCheckerState->isNoReturnCall(N))
-  return "color=\"blue\",style=\"filled\"";
-#endif
 return "";
   }
 
+  // De-duplicate some source location pretty-printing.
   static void printLocation(raw_ostream &Out, SourceLocation SLoc) {
 if (SLoc.isFileID()) {
   Out << "\\lline="
@@ -2550,6 +2534,12 @@
 << "\\l";
 }
   }
+  static void printLocation2(raw_ostream &Out, SourceLocation SLoc) {
+if (SLoc.isFileID() && GraphPrintSourceManager->isInMainFile(SLoc))
+  Out << "line " << GraphPrintSourceManager->getExpansionLineNumber(SLoc);
+else
+  SLoc.print(Out, *GraphPrintSourceManager);
+  }
 
   static std::string getNodeLabel(const ExplodedNode *N, void*){
 
@@ -2563,12 +2553,6 @@
   case ProgramPoint::BlockEntranceKind: {
 Out << "Block Entrance: B"
 << Loc.castAs().getBlock()->getBlockID();
-if (const NamedDecl *ND =
-dyn_cast(Loc.getLocationContext()->getDecl())) {
-  Out << " (";
-  ND->printName(Out);
-  Out << ")";
-}
 break;
   }
 
@@ -2693,13 +2677,6 @@
   Out << "\\l";
 }
 
-#if 0
-  // FIXME: Replace with a general scheme to determine
-  // the name of the check.
-if (GraphPrintCheckerState->isUndefControlFlow(N)) {
-  Out << "\\|Control-flow based on\\lUndefined value.\\l";
-}
-#endif
 break;
   }
 
@@ -2721,34 +2698,47 @@
 else if (Loc.getAs())
   Out << "\\lPostLValue\\l";
 
-#if 0
-  // FIXME: Replace with a general scheme to determine
-  // the name of the check.
-if (GraphPrintCheckerState->isImplicitNullDeref(N))
-  Out << "\\|Implicit-Null Dereference.\\l";
-else if (GraphPrintCheckerState->isExplicitNullDeref(N))
-  Out << "\\|Explicit-Null Dereference.\\l";
-else if (GraphPrintCheckerState->isUndefDeref(N))
-  Out << "\\|Dereference of undefialied value.\\l";
-else if (GraphPrintCheckerState->isUndefStore(N))
-  Out << "\\|Store to Undefined Loc.";
-else if (GraphPrintCheckerState->isUndefResult(N))
-  Out << "\\|Result of operation is undefined.";
-else if (GraphPrintCheckerState->isNoReturnCall(N))
-  Out << "\\|Call to function marked \"noreturn\".";
-else if (GraphPrintCheckerState->isBadCall(N))
-  Out << "\\|Call to NULL/Undefined.";
-else if (GraphPrintCheckerState->isUndefArg(N))
-  Out << "\\|Argument in call is undefined";
-#endif
-
 break;
   }
 }
 
 ProgramStateRef state = N->getState();
 Out << "\\|StateID: " << (const void*) state.get()
 << " NodeID: " << (const void*) N << "\\|";
+
+// Analysis stack backtrace.
+Out << "Location context stack (from current to outer):\\l";
+const LocationContext *LC = Loc.getLocationContext();
+unsigned Idx = 0;
+for (; LC; LC = LC->getParent(), ++Idx) {
+  Out << Idx << ". (" << (const void *)LC << ") ";
+  switch (LC->getKind()) {
+  case LocationContext::StackFrame:
+if (const NamedDecl *D = dyn_cast(LC->getDecl()))
+  Out << "Calling " << D->getQualifiedNameAsString();
+else
+  Out << "Calling anonymous code";
+if (const Stmt *S = cast(LC)->getCallSite()) {
+  Out << " at ";
+  printLocation2(Out, S->getLocStart());
+}
+break;
+  case LocationContext::Block:
+Out << "Invoking block";
+if (const Decl *D = cast(LC)->getBlockDecl()) {
+  Out << " defined at ";
+  printLocation2(Out, D->getLocStart());
+}
+break;
+  case LocationContext::Scope:
+Out << "Entering scope";
+// FIXME: Add more info once ScopeContext is activated.
+break;
+  }
+  Out << "\\l";
+}
+Out

Re: [PATCH] D22622: [analyzer] Add more info to exploded graph dumps

2016-07-23 Thread Artem Dergachev via cfe-commits
NoQ added a comment.

> We could add file names but only in cases the file name does not match the 
> main file.


Whoops, right, i guess i'd just fall back to the default source location 
printing routine for this case (or for macros).

F2198462: 3.png 

> This is not something that the patch addresses.


Yeah, just since we're all here anyway... By the way, `-analyzer-config 
prune-paths=false` is also very handy.


https://reviews.llvm.org/D22622



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


Re: [PATCH] D22334: Fix for Bug 28172 : clang crashes on invalid code (with too few arguments to __builtin_signbit) without any proper diagnostics.

2016-07-23 Thread Mayur Pandey via cfe-commits
mayurpandey added a comment.

The crash on :
int x = __builtin_signbit("1");

is not a side effect of this patch. It was failing prior to the patch as well. 
I can work on a new patch for this crash.


https://reviews.llvm.org/D22334



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


Re: [PATCH] D21962: MPITypeMismatchCheck for Clang-Tidy

2016-07-23 Thread Alexander Kornienko via cfe-commits
alexfh added a comment.

Do you have commit access?


https://reviews.llvm.org/D21962



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


Re: [PATCH] D22656: [Clang-apply-replacements] Remove custom version printing; fix some Include What You Use warnings

2016-07-23 Thread Alexander Kornienko via cfe-commits
alexfh added a comment.

My last comment might come across as somewhat harsh. I didn't mean it to be 
harsh and just wanted to say that imo, llvm code is not ready to mechanically 
applying IWYU.


Repository:
  rL LLVM

https://reviews.llvm.org/D22656



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


[PATCH] D22729: MPIBufferDerefCheck for Clang-Tidy

2016-07-23 Thread Alexander Droste via cfe-commits
Alexander_Droste created this revision.
Alexander_Droste added a reviewer: alexfh.
Alexander_Droste added a subscriber: cfe-commits.

This check verifies if a buffer passed to an MPI (Message Passing Interface)
function is sufficiently dereferenced. Buffers should be passed as a single
pointer or array. As MPI function signatures specify void * for their buffer
types, insufficiently dereferenced buffers can be passed, like for example
as double pointers or multidimensional arrays, without a compiler warning
emitted. 

Instructions on how to apply the check can be found at: 
https://github.com/0ax1/MPI-Checker/tree/master/examples


https://reviews.llvm.org/D22729

Files:
  clang-tidy/mpi/BufferDerefCheck.cpp
  clang-tidy/mpi/BufferDerefCheck.h
  clang-tidy/mpi/CMakeLists.txt
  clang-tidy/mpi/MPITidyModule.cpp
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/mpi-buffer-deref.rst
  test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
  test/clang-tidy/mpi-buffer-deref.cpp

Index: test/clang-tidy/mpi-buffer-deref.cpp
===
--- /dev/null
+++ test/clang-tidy/mpi-buffer-deref.cpp
@@ -0,0 +1,50 @@
+// RUN: %check_clang_tidy %s mpi-buffer-deref %t -- -- -I %S/Inputs/mpi-type-mismatch
+
+#include "mpimock.h"
+
+void negativeTests() {
+  char *buf;
+  MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->pointer [mpi-buffer-deref]
+
+  unsigned **buf2;
+  MPI_Send(buf2, 1, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->pointer
+
+  short buf3[1][1];
+  MPI_Send(buf3, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: array->array
+
+  long double _Complex *buf4[1];
+  MPI_Send(buf4, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->array
+
+  std::complex *buf5[1][1];
+  MPI_Send(&buf5, 1, MPI_C_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->array->array->pointer
+}
+
+void positiveTests() {
+  char buf;
+  MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+
+  unsigned *buf2;
+  MPI_Send(buf2, 1, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD);
+
+  short buf3[1][1];
+  MPI_Send(buf3[0], 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+
+  long double _Complex *buf4[1];
+  MPI_Send(*buf4, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+  long double _Complex buf5[1];
+  MPI_Send(buf5, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+  std::complex *buf6[1][1];
+  MPI_Send(*buf6[0], 1, MPI_C_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+  // Referencing an array with '&' is valid, as this also points to the
+  // beginning of the array.
+  long double _Complex buf7[1];
+  MPI_Send(&buf7, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+}
Index: test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
===
--- test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
+++ test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
@@ -24,13 +24,15 @@
 #define MPI_DATATYPE_NULL 0
 #define MPI_CHAR 0
 #define MPI_BYTE 0
+#define MPI_SHORT 0
 #define MPI_INT 0
 #define MPI_LONG 0
 #define MPI_LONG_DOUBLE 0
 #define MPI_UNSIGNED 0
 #define MPI_INT8_T 0
 #define MPI_UINT8_T 0
 #define MPI_UINT16_T 0
+#define MPI_C_FLOAT_COMPLEX 0
 #define MPI_C_LONG_DOUBLE_COMPLEX 0
 #define MPI_FLOAT 0
 #define MPI_DOUBLE 0
Index: docs/clang-tidy/checks/mpi-buffer-deref.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/mpi-buffer-deref.rst
@@ -0,0 +1,24 @@
+.. title:: clang-tidy - mpi-buffer-deref
+
+mpi-buffer-deref
+=
+
+This check verifies if a buffer passed to an MPI (Message Passing Interface)
+function is sufficiently dereferenced. Buffers should be passed as a single
+pointer or array. As MPI function signatures specify ``void *`` for their buffer
+types, insufficiently dereferenced buffers can be passed, like for example as
+double pointers or multidimensional arrays, without a compiler warning emitted.
+
+Examples:
+.. code:: c++
+  // A double pointer is passed to the MPI function.
+  char *buf;
+  MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+
+  // A multidimensional array is passed to the MPI function.
+  short buf[1][1];
+  MPI_Send(buf, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+
+  // A pointer to an array is passed to the MPI function.
+  short *buf[1];
+  MPI_Send(buf, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -108,6 +108,7 @@
mo

Re: [PATCH] D21962: MPITypeMismatchCheck for Clang-Tidy

2016-07-23 Thread Alexander Droste via cfe-commits
Alexander_Droste added a comment.

> Do you have commit access?


No, I don't have commit access.


https://reviews.llvm.org/D21962



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


Re: [PATCH] D22729: MPIBufferDerefCheck for Clang-Tidy

2016-07-23 Thread Alexander Droste via cfe-commits
Alexander_Droste updated this revision to Diff 65238.
Alexander_Droste added a comment.

- make `=` count accurate for `mpi-buffer-deref.rst`


https://reviews.llvm.org/D22729

Files:
  clang-tidy/mpi/BufferDerefCheck.cpp
  clang-tidy/mpi/BufferDerefCheck.h
  clang-tidy/mpi/CMakeLists.txt
  clang-tidy/mpi/MPITidyModule.cpp
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/mpi-buffer-deref.rst
  test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
  test/clang-tidy/mpi-buffer-deref.cpp

Index: test/clang-tidy/mpi-buffer-deref.cpp
===
--- /dev/null
+++ test/clang-tidy/mpi-buffer-deref.cpp
@@ -0,0 +1,50 @@
+// RUN: %check_clang_tidy %s mpi-buffer-deref %t -- -- -I %S/Inputs/mpi-type-mismatch
+
+#include "mpimock.h"
+
+void negativeTests() {
+  char *buf;
+  MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->pointer [mpi-buffer-deref]
+
+  unsigned **buf2;
+  MPI_Send(buf2, 1, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->pointer
+
+  short buf3[1][1];
+  MPI_Send(buf3, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: array->array
+
+  long double _Complex *buf4[1];
+  MPI_Send(buf4, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->array
+
+  std::complex *buf5[1][1];
+  MPI_Send(&buf5, 1, MPI_C_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->array->array->pointer
+}
+
+void positiveTests() {
+  char buf;
+  MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+
+  unsigned *buf2;
+  MPI_Send(buf2, 1, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD);
+
+  short buf3[1][1];
+  MPI_Send(buf3[0], 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+
+  long double _Complex *buf4[1];
+  MPI_Send(*buf4, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+  long double _Complex buf5[1];
+  MPI_Send(buf5, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+  std::complex *buf6[1][1];
+  MPI_Send(*buf6[0], 1, MPI_C_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+  // Referencing an array with '&' is valid, as this also points to the
+  // beginning of the array.
+  long double _Complex buf7[1];
+  MPI_Send(&buf7, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+}
Index: test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
===
--- test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
+++ test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
@@ -24,13 +24,15 @@
 #define MPI_DATATYPE_NULL 0
 #define MPI_CHAR 0
 #define MPI_BYTE 0
+#define MPI_SHORT 0
 #define MPI_INT 0
 #define MPI_LONG 0
 #define MPI_LONG_DOUBLE 0
 #define MPI_UNSIGNED 0
 #define MPI_INT8_T 0
 #define MPI_UINT8_T 0
 #define MPI_UINT16_T 0
+#define MPI_C_FLOAT_COMPLEX 0
 #define MPI_C_LONG_DOUBLE_COMPLEX 0
 #define MPI_FLOAT 0
 #define MPI_DOUBLE 0
Index: docs/clang-tidy/checks/mpi-buffer-deref.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/mpi-buffer-deref.rst
@@ -0,0 +1,24 @@
+.. title:: clang-tidy - mpi-buffer-deref
+
+mpi-buffer-deref
+
+
+This check verifies if a buffer passed to an MPI (Message Passing Interface)
+function is sufficiently dereferenced. Buffers should be passed as a single
+pointer or array. As MPI function signatures specify ``void *`` for their buffer
+types, insufficiently dereferenced buffers can be passed, like for example as
+double pointers or multidimensional arrays, without a compiler warning emitted.
+
+Examples:
+.. code:: c++
+  // A double pointer is passed to the MPI function.
+  char *buf;
+  MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+
+  // A multidimensional array is passed to the MPI function.
+  short buf[1][1];
+  MPI_Send(buf, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+
+  // A pointer to an array is passed to the MPI function.
+  short *buf[1];
+  MPI_Send(buf, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -108,6 +108,7 @@
modernize-use-nullptr
modernize-use-override
modernize-use-using
+   mpi-buffer-deref
mpi-type-mismatch
performance-faster-string-find
performance-for-range-copy
Index: clang-tidy/mpi/MPITidyModule.cpp
===
--- clang-tidy/mpi/MPITidyModule.cpp
+++ clang-tidy/mpi/MPITidyModule.cpp
@@ -10,6 +10,7 @@
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
+#include "BufferDer

Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Eugene Zelenko via cfe-commits
Eugene.Zelenko added a subscriber: Eugene.Zelenko.
Eugene.Zelenko added a comment.

Please mention this check in docs/ReleaseNotes.rst (in alphabetical order).

May be modernize will be better place then misc?


https://reviews.llvm.org/D22725



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


Re: [PATCH] D22717: Improve documentation of the type safety attributes

2016-07-23 Thread Aaron Ballman 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 improving the documentation!


https://reviews.llvm.org/D22717



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


Re: [PATCH] D22419: [CFG] Fix crash in thread sanitizer.

2016-07-23 Thread Devin Coughlin via cfe-commits
dcoughlin added a comment.

This is https://llvm.org/bugs/show_bug.cgi?id=28666


https://reviews.llvm.org/D22419



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


Re: [PATCH] D22729: MPIBufferDerefCheck for Clang-Tidy

2016-07-23 Thread Alexander Droste via cfe-commits
Alexander_Droste updated this revision to Diff 65239.
Alexander_Droste added a comment.

- fix two MPIdatatype tags


https://reviews.llvm.org/D22729

Files:
  clang-tidy/mpi/BufferDerefCheck.cpp
  clang-tidy/mpi/BufferDerefCheck.h
  clang-tidy/mpi/CMakeLists.txt
  clang-tidy/mpi/MPITidyModule.cpp
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/mpi-buffer-deref.rst
  test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
  test/clang-tidy/mpi-buffer-deref.cpp

Index: test/clang-tidy/mpi-buffer-deref.cpp
===
--- /dev/null
+++ test/clang-tidy/mpi-buffer-deref.cpp
@@ -0,0 +1,50 @@
+// RUN: %check_clang_tidy %s mpi-buffer-deref %t -- -- -I %S/Inputs/mpi-type-mismatch
+
+#include "mpimock.h"
+
+void negativeTests() {
+  char *buf;
+  MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->pointer [mpi-buffer-deref]
+
+  unsigned **buf2;
+  MPI_Send(buf2, 1, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->pointer
+
+  short buf3[1][1];
+  MPI_Send(buf3, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: array->array
+
+  long double _Complex *buf4[1];
+  MPI_Send(buf4, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->array
+
+  std::complex *buf5[1][1];
+  MPI_Send(&buf5, 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: buffer is insufficiently dereferenced: pointer->array->array->pointer
+}
+
+void positiveTests() {
+  char buf;
+  MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+
+  unsigned *buf2;
+  MPI_Send(buf2, 1, MPI_UNSIGNED, 0, 0, MPI_COMM_WORLD);
+
+  short buf3[1][1];
+  MPI_Send(buf3[0], 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+
+  long double _Complex *buf4[1];
+  MPI_Send(*buf4, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+  long double _Complex buf5[1];
+  MPI_Send(buf5, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+  std::complex *buf6[1][1];
+  MPI_Send(*buf6[0], 1, MPI_CXX_FLOAT_COMPLEX, 0, 0, MPI_COMM_WORLD);
+
+  // Referencing an array with '&' is valid, as this also points to the
+  // beginning of the array.
+  long double _Complex buf7[1];
+  MPI_Send(&buf7, 1, MPI_C_LONG_DOUBLE_COMPLEX, 0, 0, MPI_COMM_WORLD);
+}
Index: test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
===
--- test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
+++ test/clang-tidy/Inputs/mpi-type-mismatch/mpimock.h
@@ -24,13 +24,15 @@
 #define MPI_DATATYPE_NULL 0
 #define MPI_CHAR 0
 #define MPI_BYTE 0
+#define MPI_SHORT 0
 #define MPI_INT 0
 #define MPI_LONG 0
 #define MPI_LONG_DOUBLE 0
 #define MPI_UNSIGNED 0
 #define MPI_INT8_T 0
 #define MPI_UINT8_T 0
 #define MPI_UINT16_T 0
+#define MPI_C_FLOAT_COMPLEX 0
 #define MPI_C_LONG_DOUBLE_COMPLEX 0
 #define MPI_FLOAT 0
 #define MPI_DOUBLE 0
Index: docs/clang-tidy/checks/mpi-buffer-deref.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/mpi-buffer-deref.rst
@@ -0,0 +1,24 @@
+.. title:: clang-tidy - mpi-buffer-deref
+
+mpi-buffer-deref
+
+
+This check verifies if a buffer passed to an MPI (Message Passing Interface)
+function is sufficiently dereferenced. Buffers should be passed as a single
+pointer or array. As MPI function signatures specify ``void *`` for their buffer
+types, insufficiently dereferenced buffers can be passed, like for example as
+double pointers or multidimensional arrays, without a compiler warning emitted.
+
+Examples:
+.. code:: c++
+  // A double pointer is passed to the MPI function.
+  char *buf;
+  MPI_Send(&buf, 1, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
+
+  // A multidimensional array is passed to the MPI function.
+  short buf[1][1];
+  MPI_Send(buf, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
+
+  // A pointer to an array is passed to the MPI function.
+  short *buf[1];
+  MPI_Send(buf, 1, MPI_SHORT, 0, 0, MPI_COMM_WORLD);
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -108,6 +108,7 @@
modernize-use-nullptr
modernize-use-override
modernize-use-using
+   mpi-buffer-deref
mpi-type-mismatch
performance-faster-string-find
performance-for-range-copy
Index: clang-tidy/mpi/MPITidyModule.cpp
===
--- clang-tidy/mpi/MPITidyModule.cpp
+++ clang-tidy/mpi/MPITidyModule.cpp
@@ -10,6 +10,7 @@
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
+#include "BufferDerefCheck.h"
 #include "

Re: [PATCH] D22712: Remove FileEntry copy-constructor

2016-07-23 Thread Saleem Abdulrasool via cfe-commits
compnerd accepted this revision.
compnerd added a reviewer: compnerd.
compnerd added a comment.
This revision is now accepted and ready to land.

Do you have commit access?


https://reviews.llvm.org/D22712



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


Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Aaron Ballman via cfe-commits
aaron.ballman added a comment.

> Using std::copy opens up the possibility of type-aware optimizations which 
> are not possible with memcpy.


To my knowledge, those type-aware optimizations are for transforming copies 
involving trivially-copyable types into calls to memcpy(). What other 
optimizations does this check enable?


Repository:
  rL LLVM

https://reviews.llvm.org/D22725



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


Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Jonas Devlieghere via cfe-commits
JDevlieghere added a comment.

In https://reviews.llvm.org/D22725#493940, @aaron.ballman wrote:

> > Using std::copy opens up the possibility of type-aware optimizations which 
> > are not possible with memcpy.
>
>
> To my knowledge, those type-aware optimizations are for transforming copies 
> involving trivially-copyable types into calls to memcpy(). What other 
> optimizations does this check enable?


I might be mistaken, but I understood that a call to std::copy (whether or not 
specialized for certain types) might get inlined, while a call to memcpy is 
typically not.


Repository:
  rL LLVM

https://reviews.llvm.org/D22725



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


Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Piotr Padlewski via cfe-commits
Prazek added a subscriber: Prazek.
Prazek added a comment.

Thanks for the contribution. Is it your first check?

Some main issues:

1. I think it would be much better to move this check to modernize module. I 
think the name 'modernize-use-copy' would follow the convention, or just

'modernize-replace-memcpy' also works, maybe it is even better. Your choice. 
Use rename_check.py to rename the check.

2. Please add include fixer that will include  if it is not yet 
included, so the code will compile after changes.

Look at DeprecatedHeadersCheck.cpp or PassByValueCheck ( or grep for 
registerPPCallbacks)

3. The extra parens are not ideal thing. Can you describe (with examples) in 
which situations it would not compile/ something bad would happen if you 
wouldn't put the parens? I think you could check it in matchers and then apply 
parens or not.

4. Have you run the check on LLVM code base? It uses std::copy in many places. 
If after running with -fix all the memcpys will be gone (check if if finds 
anything after second run) and the code will compile and tests will not fail 
then it means that your check fully works!



Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:25
@@ +24,3 @@
+void ReplaceMemcpyCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+  callExpr(callee(functionDecl(hasName("memcpy".bind("expr"), this);

add if here to discard the non c++ calls. (the same as you see in most of the 
checks)


Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:26
@@ +25,3 @@
+  Finder->addMatcher(
+  callExpr(callee(functionDecl(hasName("memcpy".bind("expr"), this);
+}

you can check argument count here.


Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:40-41
@@ +39,4 @@
+
+  if (MatchedExpr->getNumArgs() != 3)
+return;
+

so this can be checked in matcher 


Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:55
@@ +54,3 @@
+  diag(MatchedExpr->getExprLoc(), "Use std::copy instead of memcyp")
+  << FixItHint::CreateReplacement(MatchedExpr->getSourceRange(), 
Insertion);
+}

don't make replacement if it is in macro (use .isMacroID on the location).

Also add tests with macros.


Comment at: clang-tidy/misc/ReplaceMemcpyCheck.h:30
@@ +29,3 @@
+
+  static StringRef GetText(const Expr *Expression, const SourceManager &SM,
+   const LangOptions &LangOpts);

If it is static, then move it to .cpp file.

You could also remove static and arguments that you have access from class and 
move it to private.

Also I think the function name convention is lowerCamelCase


Comment at: test/clang-tidy/misc-replace-memcpy.cpp:3-5
@@ +2,5 @@
+
+#include 
+#include 
+#include 
+

don't include the stl, because it will make the test undebugable (the ast is 
too big)

Mock the functions that you need - std::copy and std::memcpy. you don't have to 
give definition, but just make sure the declaration of the functions are the 
same.


Also check if check will add  here.


Repository:
  rL LLVM

https://reviews.llvm.org/D22725



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


Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Aaron Ballman via cfe-commits
aaron.ballman added a comment.

In https://reviews.llvm.org/D22725#493942, @JDevlieghere wrote:

> In https://reviews.llvm.org/D22725#493940, @aaron.ballman wrote:
>
> > > Using std::copy opens up the possibility of type-aware optimizations 
> > > which are not possible with memcpy.
> >
> >
> > To my knowledge, those type-aware optimizations are for transforming copies 
> > involving trivially-copyable types into calls to memcpy(). What other 
> > optimizations does this check enable?
>
>
> I might be mistaken, but I understood that a call to std::copy (whether or 
> not specialized for certain types) might get inlined, while a call to memcpy 
> is typically not.


The optimizer can be quite smart about memcpy(). For instance: 
https://godbolt.org/g/INfHWE

If we know of specific cases where std::memcpy() is used, but std::copy() will 
provide better performance metrics, that would be really interesting to know.


Repository:
  rL LLVM

https://reviews.llvm.org/D22725



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


Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Piotr Padlewski via cfe-commits
Prazek added a comment.

In https://reviews.llvm.org/D22725#493942, @JDevlieghere wrote:

> In https://reviews.llvm.org/D22725#493940, @aaron.ballman wrote:
>
> > > Using std::copy opens up the possibility of type-aware optimizations 
> > > which are not possible with memcpy.
> >
> >
> > To my knowledge, those type-aware optimizations are for transforming copies 
> > involving trivially-copyable types into calls to memcpy(). What other 
> > optimizations does this check enable?
>
>
> I might be mistaken, but I understood that a call to std::copy (whether or 
> not specialized for certain types) might get inlined, while a call to memcpy 
> is typically not.


So if it is something trivially copyable (just copying bytes) then std::copy 
would probably call memcpy inside - so it won't be optimization in our case 
(even if it will get inlined).

But it will definitelly make code cleaner and won't be slower, which would be 
good to mention in docs.


Repository:
  rL LLVM

https://reviews.llvm.org/D22725



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


Re: [PATCH] D22208: [clang-tidy] Fixes to modernize-use-emplace

2016-07-23 Thread Piotr Padlewski via cfe-commits
Prazek removed rL LLVM as the repository for this revision.
Prazek updated this revision to Diff 65243.
Prazek added a comment.

Ok works right now. I don't know why but I could not reproduce the error in 
test file, but I manged to fix it.


https://reviews.llvm.org/D22208

Files:
  clang-tidy/modernize/UseEmplaceCheck.cpp
  clang-tidy/modernize/UseEmplaceCheck.h
  clang-tidy/utils/Matchers.h
  docs/clang-tidy/checks/modernize-use-emplace.rst
  test/clang-tidy/modernize-use-emplace.cpp

Index: test/clang-tidy/modernize-use-emplace.cpp
===
--- test/clang-tidy/modernize-use-emplace.cpp
+++ test/clang-tidy/modernize-use-emplace.cpp
@@ -1,4 +1,7 @@
-// RUN: %check_clang_tidy %s modernize-use-emplace %t
+// RUN: %check_clang_tidy %s modernize-use-emplace %t -- \
+// RUN:   -config="{CheckOptions: \
+// RUN: [{key: modernize-use-emplace.ContainersWithPushBack, \
+// RUN:   value: '::std::vector; ::std::list; ::std::deque; llvm::LikeASmallVector'}]}" -- -std=c++11
 
 namespace std {
 template 
@@ -9,6 +12,7 @@
 
   template 
   void emplace_back(Args &&... args){};
+  ~vector();
 };
 template 
 class list {
@@ -18,6 +22,7 @@
 
   template 
   void emplace_back(Args &&... args){};
+  ~list();
 };
 
 template 
@@ -28,6 +33,7 @@
 
   template 
   void emplace_back(Args &&... args){};
+  ~deque();
 };
 
 template 
@@ -54,10 +60,24 @@
 template 
 class unique_ptr {
 public:
-  unique_ptr(T *) {}
+  explicit unique_ptr(T *) {}
+  ~unique_ptr();
 };
 } // namespace std
 
+namespace llvm {
+template 
+class LikeASmallVector {
+public:
+  void push_back(const T &) {}
+  void push_back(T &&) {}
+
+  template 
+  void emplace_back(Args &&... args){};
+};
+
+} // llvm
+
 void testInts() {
   std::vector v;
   v.push_back(42);
@@ -72,6 +92,7 @@
   Something(int a, int b = 41) {}
   Something() {}
   void push_back(Something);
+  int getInt() { return 42; }
 };
 
 struct Convertable {
@@ -103,6 +124,15 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
   // CHECK-FIXES: v.emplace_back();
 
+  Something Different;
+  v.push_back(Something(Different.getInt(), 42));
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+  // CHECK-FIXES: v.emplace_back(Different.getInt(), 42);
+
+  v.push_back(Different.getInt());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+  // CHECK-FIXES: v.emplace_back(Different.getInt());
+
   v.push_back(42);
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
   // CHECK-FIXES: v.emplace_back(42);
@@ -117,6 +147,23 @@
   v.push_back(s);
 }
 
+template 
+void dependOnElem() {
+  std::vector v;
+  v.push_back(ElemType(42));
+}
+
+template 
+void dependOnContainer() {
+  ContainerType v;
+  v.push_back(Something(42));
+}
+
+void callDependent() {
+  dependOnElem();
+  dependOnContainer>();
+}
+
 void test2() {
   std::vector v;
   v.push_back(Zoz(Something(21, 37)));
@@ -130,12 +177,20 @@
   v.push_back(getZoz(Something(1, 2)));
 }
 
+struct GetPair {
+  std::pair getPair();
+};
 void testPair() {
   std::vector> v;
   v.push_back(std::pair(1, 2));
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
   // CHECK-FIXES: v.emplace_back(1, 2);
 
+  GetPair g;
+  v.push_back(g.getPair());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
+  // CHECK-FIXES: v.emplace_back(g.getPair());
+
   std::vector> v2;
   v2.push_back(std::pair(Something(42, 42), Zoz(Something(21, 37;
   // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
@@ -206,14 +261,14 @@
   v.push_back(new int(5));
 
   std::vector> v2;
-  v2.push_back(new int(42));
+  v2.push_back(std::unique_ptr(new int(42)));
   // This call can't be replaced with emplace_back.
   // If emplacement will fail (not enough memory to add to vector)
   // we will have leak of int because unique_ptr won't be constructed
   // (and destructed) as in push_back case.
 
   auto *ptr = new int;
-  v2.push_back(ptr);
+  v2.push_back(std::unique_ptr(ptr));
   // Same here
 }
 
@@ -240,6 +295,11 @@
   d.push_back(Something(42));
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
   // CHECK-FIXES: d.emplace_back(42);
+
+  llvm::LikeASmallVector ls;
+  ls.push_back(Something(42));
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use emplace_back
+  // CHECK-FIXES: ls.emplace_back(42);
 }
 
 class IntWrapper {
@@ -336,3 +396,29 @@
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use emplace_back
   // CHECK-FIXES: v.emplace_back(42, var);
 }
+
+class PrivateCtor {
+  PrivateCtor(int z);
+
+public:
+  void doStuff() {
+std::vector v;
+// This should not change it because emplace back doesn't have permission.
+// Check currently doesn't support friend delcarations because pretty much
+// nobody would want to be friend with std::vector :(.
+v.push_back(PrivateCtor(42));
+  }
+};
+
+struct WithDtor {
+  WithDtor(int) {}
+  ~WithDtor();
+};
+
+void testWithDtor() {
+  std::ve

Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Jonas Devlieghere via cfe-commits
JDevlieghere updated this revision to Diff 65246.
JDevlieghere added a comment.

- Added new check to release notes
- Renamed to modernize-use-copy
- Addressed comments from Prazek


Repository:
  rL LLVM

https://reviews.llvm.org/D22725

Files:
  clang-tidy/modernize/CMakeLists.txt
  clang-tidy/modernize/ModernizeTidyModule.cpp
  clang-tidy/modernize/UseCopyCheck.cpp
  clang-tidy/modernize/UseCopyCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/modernize-use-copy.rst
  test/clang-tidy/modernize-use-copy.cpp

Index: test/clang-tidy/modernize-use-copy.cpp
===
--- /dev/null
+++ test/clang-tidy/modernize-use-copy.cpp
@@ -0,0 +1,38 @@
+// RUN: %check_clang_tidy %s modernize-use-copy %t
+
+// CHECK-FIXES: #include 
+
+namespace std {
+typedef unsigned int size_t;
+void *memcpy(void *dest, const void *src, std::size_t count);
+
+template 
+OutputIt copy(InputIt first, InputIt last, OutputIt d_first);
+}
+
+void f() {
+  char foo[] = "foo", bar[3], baz[3];
+  std::memcpy(bar, foo, sizeof bar);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Use std::copy instead of memcpy
+  // [modernize-use-copy]
+  // CHECK-FIXES: std::copy(foo, (foo) + (sizeof bar), bar);
+
+  bool b = false;
+  std::memcpy(baz, b ? foo : bar, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Use std::copy instead of memcpy
+  // [modernize-use-copy]
+  // CHECK-FIXES: std::copy(b ? foo : bar, (b ? foo : bar) + (3), baz);
+
+  std::memcpy(bar, foo, sizeof bar);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Use std::copy instead of memcpy
+  // [modernize-use-copy]
+  // CHECK-FIXES: std::copy(foo, (foo) + (sizeof bar), bar);
+
+  std::copy(foo, foo + sizeof bar, bar);
+}
+
+#define memcpy(dest, src, len) std::memcpy((dest), (src), (len))
+void g() {
+  char foo[] = "foo", bar[3];
+  memcpy(bar, foo, sizeof bar);
+}
Index: docs/clang-tidy/checks/modernize-use-copy.rst
===
--- /dev/null
+++ docs/clang-tidy/checks/modernize-use-copy.rst
@@ -0,0 +1,32 @@
+.. title:: clang-tidy - modernize-use-copy
+
+modernize-use-copy
+==
+
+Replaces ``memcpy`` with ``std::copy``. This makes the code cleaner and allows
+the compiler to decide on the preferred implementation.
+
+Example:
+
+.. code:: c++
+
+std::memcpy(dest, source, sizeof dest);
+
+// transforms to:
+
+std::copy(source, (source) + (sizeof dest), dest);
+
+Parenthesis are added devensively to preclude the summation from taking
+precedence over operators used in the arguments of ``memcpy``.
+
+.. code:: c++
+
+std::memcpy(baz, b ? foo : bar, 3);
+
+// transforms to:
+
+std::copy(b ? foo : bar, (b ? foo : bar) + (3), baz);
+
+// but without the parenthesis it would have become the equivalent of:
+
+std::copy(b ? foo : bar, b ? foo : (bar + 3), baz);
Index: docs/clang-tidy/checks/list.rst
===
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -29,6 +29,7 @@
cppcoreguidelines-pro-type-static-cast-downcast
cppcoreguidelines-pro-type-union-access
cppcoreguidelines-pro-type-vararg
+   cppcoreguidelines-slicing
google-build-explicit-make-pair
google-build-namespaces
google-build-using-namespace
@@ -103,6 +104,7 @@
modernize-shrink-to-fit
modernize-use-auto
modernize-use-bool-literals
+   modernize-use-copy
modernize-use-default
modernize-use-emplace
modernize-use-nullptr
Index: docs/ReleaseNotes.rst
===
--- docs/ReleaseNotes.rst
+++ docs/ReleaseNotes.rst
@@ -64,6 +64,11 @@
 
   Flags slicing of member variables or vtable.
 
+- New `modernize-replace-memcpy
+  `_ check
+
+  Replaces calls to memcpy with std::copy.
+
 Improvements to include-fixer
 -
 
Index: clang-tidy/modernize/UseCopyCheck.h
===
--- /dev/null
+++ clang-tidy/modernize/UseCopyCheck.h
@@ -0,0 +1,44 @@
+//===--- UseCopyCheck.h - clang-tidy-*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_COPY_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_COPY_H
+
+#include "../ClangTidy.h"
+#include "../utils/IncludeInserter.h"
+
+namespace clang {
+namespace tidy {
+namespace modernize {
+
+/// Replaces memcpy with std::copy
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize-use-copy.html
+clas

Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Jonas Devlieghere via cfe-commits
JDevlieghere added a comment.

In https://reviews.llvm.org/D22725#493947, @Prazek wrote:

> Thanks for the contribution. Is it your first check?


Yes, it is! :-)

> Some main issues:

> 

> 1. I think it would be much better to move this check to modernize module. I 
> think the name 'modernize-use-copy' would follow the convention, or just 
> 'modernize-replace-memcpy' also works, maybe it is even better. Your choice. 
> Use rename_check.py to rename the check.


Agreed, I moved and renamed the check.

> 2. Please add include fixer that will include  if it is not yet 
> included, so the code will compile after changes. Look at 
> DeprecatedHeadersCheck.cpp or PassByValueCheck ( or grep for 
> registerPPCallbacks)


Done

> 3. The extra parens are not ideal thing. Can you describe (with examples) in 
> which situations it would not compile/ something bad would happen if you 
> wouldn't put the parens? I think you could check it in matchers and then 
> apply parens or not.


I have included an example in the documentation with the ternary conditional 
operator. I agree that it's not ideal, but I tried to be defensive. Basically 
anything with lower precedence than the + operator might cause an issue, and 
this is quite a lot...

> 4. Have you run the check on LLVM code base? It uses std::copy in many 
> places. If after running with -fix all the memcpys will be gone (check if if 
> finds anything after second run) and the code will compile and tests will not 
> fail then it means that your check fully works!


Doing this as we speak!


Repository:
  rL LLVM

https://reviews.llvm.org/D22725



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


Re: [PATCH] D20811: [analyzer] Model some library functions

2016-07-23 Thread Artem Dergachev via cfe-commits
NoQ updated this revision to Diff 65248.
NoQ marked 11 inline comments as done.
NoQ added a comment.

Renamed the checker as **xazax.hun** suggested, added a lot more comments, done 
with inline comments :)


https://reviews.llvm.org/D20811

Files:
  include/clang/StaticAnalyzer/Checkers/Checkers.td
  lib/StaticAnalyzer/Checkers/CMakeLists.txt
  lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
  test/Analysis/std-library-functions.c

Index: test/Analysis/std-library-functions.c
===
--- test/Analysis/std-library-functions.c
+++ test/Analysis/std-library-functions.c
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=unix.StdLibraryFunctions,debug.ExprInspection -verify %s
+
+void clang_analyzer_eval(int);
+int glob;
+
+typedef struct FILE FILE;
+int getc(FILE *);
+#define EOF -1
+void test_getc(FILE *fp) {
+  int x;
+  while ((x = getc(fp)) != EOF) {
+clang_analyzer_eval(x > 255); // expected-warning{{FALSE}}
+clang_analyzer_eval(x >= 0); // expected-warning{{TRUE}}
+  }
+}
+
+typedef unsigned long size_t;
+typedef signed long ssize_t;
+ssize_t write(int, const void *, size_t);
+void test_write(int fd, char *buf) {
+  glob = 1;
+  ssize_t x = write(fd, buf, 10);
+  clang_analyzer_eval(glob); // expected-warning{{UNKNOWN}}
+  if (x >= 0)
+clang_analyzer_eval(x <= 10); // expected-warning{{TRUE}}
+  else
+clang_analyzer_eval(x == -1); // expected-warning{{TRUE}}
+}
+
+size_t fread(void *, size_t, size_t, FILE *);
+void test_fread(FILE *fp, int *buf) {
+  size_t x = fread(buf, sizeof(int), 10, fp);
+  clang_analyzer_eval(x <= 10); // expected-warning{{TRUE}}
+}
+
+ssize_t getline(char **, size_t *, FILE *);
+void test_getline(FILE *fp) {
+  char *line = 0;
+  size_t n = 0;
+  ssize_t len;
+  while ((len = getline(&line, &n, fp)) != -1) {
+clang_analyzer_eval(len == 0); // expected-warning{{FALSE}}
+  }
+}
+
+int isascii(int);
+void test_isascii(int x) {
+  clang_analyzer_eval(isascii(123)); // expected-warning{{TRUE}}
+  clang_analyzer_eval(isascii(-1)); // expected-warning{{FALSE}}
+  if (isascii(x)) {
+clang_analyzer_eval(x < 128); // expected-warning{{TRUE}}
+clang_analyzer_eval(x >= 0); // expected-warning{{TRUE}}
+  } else {
+if (x > 42)
+  clang_analyzer_eval(x >= 128); // expected-warning{{TRUE}}
+else
+  clang_analyzer_eval(x < 0); // expected-warning{{TRUE}}
+  }
+  glob = 1;
+  isascii('a');
+  clang_analyzer_eval(glob); // expected-warning{{TRUE}}
+}
+
+int islower(int);
+void test_islower(int x) {
+  clang_analyzer_eval(islower('x')); // expected-warning{{TRUE}}
+  clang_analyzer_eval(islower('X')); // expected-warning{{FALSE}}
+  if (islower(x))
+clang_analyzer_eval(x < 'a'); // expected-warning{{FALSE}}
+}
+
+int getchar(void);
+void test_getchar() {
+  int x = getchar();
+  if (x == EOF)
+return;
+  clang_analyzer_eval(x < 0); // expected-warning{{FALSE}}
+  clang_analyzer_eval(x < 256); // expected-warning{{TRUE}}
+}
+
+int isalpha(int);
+void test_isalpha() {
+  clang_analyzer_eval(isalpha(']')); // expected-warning{{FALSE}}
+  clang_analyzer_eval(isalpha('Q')); // expected-warning{{TRUE}}
+  clang_analyzer_eval(isalpha(128)); // expected-warning{{UNKNOWN}}
+}
+
+int isalnum(int);
+void test_alnum() {
+  clang_analyzer_eval(isalnum('1')); // expected-warning{{TRUE}}
+  clang_analyzer_eval(isalnum(')')); // expected-warning{{FALSE}}
+}
+
+int isblank(int);
+void test_isblank() {
+  clang_analyzer_eval(isblank('\t')); // expected-warning{{TRUE}}
+  clang_analyzer_eval(isblank(' ')); // expected-warning{{TRUE}}
+  clang_analyzer_eval(isblank('\n')); // expected-warning{{FALSE}}
+}
+
+int ispunct(int);
+void test_ispunct(int x) {
+  clang_analyzer_eval(ispunct(' ')); // expected-warning{{FALSE}}
+  clang_analyzer_eval(ispunct(-1)); // expected-warning{{FALSE}}
+  clang_analyzer_eval(ispunct('#')); // expected-warning{{TRUE}}
+  clang_analyzer_eval(ispunct('_')); // expected-warning{{TRUE}}
+  if (ispunct(x))
+clang_analyzer_eval(x < 127); // expected-warning{{TRUE}}
+}
Index: lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
===
--- lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -0,0 +1,831 @@
+//=== StdLibraryFunctionsChecker.cpp - Model standard functions -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===--===//
+//
+// This checker improves modeling of a few simple library functions.
+// It does not throw warnings.
+//
+// This checker provides a specification format - `FunctionSpecTy' - and
+// contains descriptions of some library functions in this format. Each
+// specification con

Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Eugene Zelenko via cfe-commits
Eugene.Zelenko added inline comments.


Comment at: docs/ReleaseNotes.rst:70
@@ +69,3 @@
+
+  Replaces calls to memcpy with std::copy.
+

Please highlight memcpy and std::copy with `` as it done in documentation.


Repository:
  rL LLVM

https://reviews.llvm.org/D22725



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


Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Aaron Ballman via cfe-commits
On Sat, Jul 23, 2016 at 1:38 PM, Piotr Padlewski
 wrote:
> Prazek added a subscriber: Prazek.
> Prazek added a comment.
>
> Thanks for the contribution. Is it your first check?
>
> Some main issues:
>
> 1. I think it would be much better to move this check to modernize module. I 
> think the name 'modernize-use-copy' would follow the convention, or just
>
> 'modernize-replace-memcpy' also works, maybe it is even better. Your choice.
> Use rename_check.py to rename the check.

Why "modernize"? There's nothing modern about std::copy(), so I don't
see this as really relating to modernizing someone's code base.

Truth be told, I'm not entirely convinced this is a good check to have
-- I'm still wondering if there's a compelling use case where
std::copy() is an improvement over std::memcpy(). I'm guessing one
exists, but I've not seen it stated here.

~Aaron

>
> 2. Please add include fixer that will include  if it is not yet 
> included, so the code will compile after changes.
>
> Look at DeprecatedHeadersCheck.cpp or PassByValueCheck ( or grep for 
> registerPPCallbacks)
>
> 3. The extra parens are not ideal thing. Can you describe (with examples) in 
> which situations it would not compile/ something bad would happen if you 
> wouldn't put the parens? I think you could check it in matchers and then 
> apply parens or not.
>
> 4. Have you run the check on LLVM code base? It uses std::copy in many 
> places. If after running with -fix all the memcpys will be gone (check if if 
> finds anything after second run) and the code will compile and tests will not 
> fail then it means that your check fully works!
>
>
> 
> Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:25
> @@ +24,3 @@
> +void ReplaceMemcpyCheck::registerMatchers(MatchFinder *Finder) {
> +  Finder->addMatcher(
> +  callExpr(callee(functionDecl(hasName("memcpy".bind("expr"), this);
> 
> add if here to discard the non c++ calls. (the same as you see in most of the 
> checks)
>
> 
> Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:26
> @@ +25,3 @@
> +  Finder->addMatcher(
> +  callExpr(callee(functionDecl(hasName("memcpy".bind("expr"), this);
> +}
> 
> you can check argument count here.
>
> 
> Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:40-41
> @@ +39,4 @@
> +
> +  if (MatchedExpr->getNumArgs() != 3)
> +return;
> +
> 
> so this can be checked in matcher
>
> 
> Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:55
> @@ +54,3 @@
> +  diag(MatchedExpr->getExprLoc(), "Use std::copy instead of memcyp")
> +  << FixItHint::CreateReplacement(MatchedExpr->getSourceRange(), 
> Insertion);
> +}
> 
> don't make replacement if it is in macro (use .isMacroID on the location).
>
> Also add tests with macros.
>
> 
> Comment at: clang-tidy/misc/ReplaceMemcpyCheck.h:30
> @@ +29,3 @@
> +
> +  static StringRef GetText(const Expr *Expression, const SourceManager &SM,
> +   const LangOptions &LangOpts);
> 
> If it is static, then move it to .cpp file.
>
> You could also remove static and arguments that you have access from class 
> and move it to private.
>
> Also I think the function name convention is lowerCamelCase
>
> 
> Comment at: test/clang-tidy/misc-replace-memcpy.cpp:3-5
> @@ +2,5 @@
> +
> +#include 
> +#include 
> +#include 
> +
> 
> don't include the stl, because it will make the test undebugable (the ast is 
> too big)
>
> Mock the functions that you need - std::copy and std::memcpy. you don't have 
> to give definition, but just make sure the declaration of the functions are 
> the same.
>
>
> Also check if check will add  here.
>
>
> Repository:
>   rL LLVM
>
> https://reviews.llvm.org/D22725
>
>
>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D22725: [clang-tidy] Add check 'misc-replace-memcpy'

2016-07-23 Thread Aaron Ballman via cfe-commits
On Sat, Jul 23, 2016 at 4:16 PM, Aaron Ballman  wrote:
> On Sat, Jul 23, 2016 at 1:38 PM, Piotr Padlewski
>  wrote:
>> Prazek added a subscriber: Prazek.
>> Prazek added a comment.
>>
>> Thanks for the contribution. Is it your first check?
>>
>> Some main issues:
>>
>> 1. I think it would be much better to move this check to modernize module. I 
>> think the name 'modernize-use-copy' would follow the convention, or just
>>
>> 'modernize-replace-memcpy' also works, maybe it is even better. Your choice.
>> Use rename_check.py to rename the check.
>
> Why "modernize"? There's nothing modern about std::copy(), so I don't
> see this as really relating to modernizing someone's code base.
>
> Truth be told, I'm not entirely convinced this is a good check to have
> -- I'm still wondering if there's a compelling use case where
> std::copy() is an improvement over std::memcpy(). I'm guessing one
> exists, but I've not seen it stated here.

Btw, to be clear -- this wasn't meant to discourage you from working
on this patch (it's very much appreciated!), but to encourage you to
provide some more context around what utility the patch is expected to
provide so that we can review it with that in mind. :-)

Thanks!

~Aaron

>
> ~Aaron
>
>>
>> 2. Please add include fixer that will include  if it is not yet 
>> included, so the code will compile after changes.
>>
>> Look at DeprecatedHeadersCheck.cpp or PassByValueCheck ( or grep for 
>> registerPPCallbacks)
>>
>> 3. The extra parens are not ideal thing. Can you describe (with examples) in 
>> which situations it would not compile/ something bad would happen if you 
>> wouldn't put the parens? I think you could check it in matchers and then 
>> apply parens or not.
>>
>> 4. Have you run the check on LLVM code base? It uses std::copy in many 
>> places. If after running with -fix all the memcpys will be gone (check if if 
>> finds anything after second run) and the code will compile and tests will 
>> not fail then it means that your check fully works!
>>
>>
>> 
>> Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:25
>> @@ +24,3 @@
>> +void ReplaceMemcpyCheck::registerMatchers(MatchFinder *Finder) {
>> +  Finder->addMatcher(
>> +  callExpr(callee(functionDecl(hasName("memcpy".bind("expr"), this);
>> 
>> add if here to discard the non c++ calls. (the same as you see in most of 
>> the checks)
>>
>> 
>> Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:26
>> @@ +25,3 @@
>> +  Finder->addMatcher(
>> +  callExpr(callee(functionDecl(hasName("memcpy".bind("expr"), this);
>> +}
>> 
>> you can check argument count here.
>>
>> 
>> Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:40-41
>> @@ +39,4 @@
>> +
>> +  if (MatchedExpr->getNumArgs() != 3)
>> +return;
>> +
>> 
>> so this can be checked in matcher
>>
>> 
>> Comment at: clang-tidy/misc/ReplaceMemcpyCheck.cpp:55
>> @@ +54,3 @@
>> +  diag(MatchedExpr->getExprLoc(), "Use std::copy instead of memcyp")
>> +  << FixItHint::CreateReplacement(MatchedExpr->getSourceRange(), 
>> Insertion);
>> +}
>> 
>> don't make replacement if it is in macro (use .isMacroID on the location).
>>
>> Also add tests with macros.
>>
>> 
>> Comment at: clang-tidy/misc/ReplaceMemcpyCheck.h:30
>> @@ +29,3 @@
>> +
>> +  static StringRef GetText(const Expr *Expression, const SourceManager &SM,
>> +   const LangOptions &LangOpts);
>> 
>> If it is static, then move it to .cpp file.
>>
>> You could also remove static and arguments that you have access from class 
>> and move it to private.
>>
>> Also I think the function name convention is lowerCamelCase
>>
>> 
>> Comment at: test/clang-tidy/misc-replace-memcpy.cpp:3-5
>> @@ +2,5 @@
>> +
>> +#include 
>> +#include 
>> +#include 
>> +
>> 
>> don't include the stl, because it will make the test undebugable (the ast is 
>> too big)
>>
>> Mock the functions that you need - std::copy and std::memcpy. you don't have 
>> to give definition, but just make sure the declaration of the functions are 
>> the same.
>>
>>
>> Also check if check will add  here.
>>
>>
>> Repository:
>>   rL LLVM
>>
>> https://reviews.llvm.org/D22725
>>
>>
>>
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


Re: [PATCH] D20787: Fix undefined behavior in __hash_table

2016-07-23 Thread Eric Fiselier via cfe-commits
EricWF updated this revision to Diff 65253.
EricWF added a comment.

- Merge with upstream.
- Cleanup logic in iterator
- Remove UBSAN blacklist. It's no longer needed. We have no more UB.


https://reviews.llvm.org/D20787

Files:
  include/__config
  include/__debug
  include/__hash_table
  test/libcxx/test/config.py
  test/ubsan_blacklist.txt

Index: test/ubsan_blacklist.txt
===
--- test/ubsan_blacklist.txt
+++ /dev/null
@@ -1 +0,0 @@
-fun:*__hash_table*
Index: test/libcxx/test/config.py
===
--- test/libcxx/test/config.py
+++ test/libcxx/test/config.py
@@ -627,13 +627,10 @@
 self.config.available_features.add('msan')
 self.config.available_features.add('sanitizer-new-delete')
 elif san == 'Undefined':
-blacklist = os.path.join(self.libcxx_src_root,
- 'test/ubsan_blacklist.txt')
 self.cxx.flags += ['-fsanitize=undefined',
'-fno-sanitize=vptr,function,float-divide-by-zero',
-   '-fno-sanitize-recover=all',
-   '-fsanitize-blacklist=' + blacklist]
-self.cxx.compile_flags += ['-O3']
+   '-fno-sanitize-recover=all']
+self.cxx.compile_flags += ['-O2']
 self.env['UBSAN_OPTIONS'] = 'print_stacktrace=1'
 self.config.available_features.add('ubsan')
 elif san == 'Thread':
Index: include/__hash_table
===
--- include/__hash_table
+++ include/__hash_table
@@ -59,9 +59,38 @@
 template 
 struct __hash_node_base
 {
+typedef typename pointer_traits<_NodePtr>::element_type __node_type;
 typedef __hash_node_base __first_node;
+typedef typename __rebind_pointer<_NodePtr, __first_node>::type __node_base_pointer;
+typedef _NodePtr __node_pointer;
+
+#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB)
+  typedef __node_base_pointer __next_pointer;
+#else
+  typedef typename conditional<
+  is_pointer<__node_pointer>::value,
+  __node_base_pointer,
+  __node_pointer>::type   __next_pointer;
+#endif
 
-_NodePtr__next_;
+__next_pointer__next_;
+
+_LIBCPP_INLINE_VISIBILITY
+__next_pointer __ptr() _NOEXCEPT {
+return static_cast<__next_pointer>(
+pointer_traits<__node_base_pointer>::pointer_to(*this));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+__node_pointer __upcast() _NOEXCEPT {
+return static_cast<__node_pointer>(
+pointer_traits<__node_base_pointer>::pointer_to(*this));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+size_t __hash() const _NOEXCEPT {
+return static_cast<__node_type const&>(*this).__hash_;
+}
 
 _LIBCPP_INLINE_VISIBILITY __hash_node_base() _NOEXCEPT : __next_(nullptr) {}
 };
@@ -75,7 +104,7 @@
 {
 typedef _Tp __node_value_type;
 
-size_t __hash_;
+size_t__hash_;
 __node_value_type __value_;
 };
 
@@ -219,11 +248,14 @@
   typedef typename __rebind_pointer<_NodePtr, __node_base_type>::type
  __node_base_pointer;
 
+  typedef typename __node_base_type::__next_pointer  __next_pointer;
+
   typedef _Tp __node_value_type;
   typedef typename __rebind_pointer<_VoidPtr, __node_value_type>::type
   __node_value_type_pointer;
   typedef typename __rebind_pointer<_VoidPtr, const __node_value_type>::type
 __const_node_value_type_pointer;
+
 private:
 static_assert(!is_const<__node_type>::value,
 "_NodePtr should never be a pointer to const");
@@ -233,8 +265,6 @@
   _NodePtr>::value), "_VoidPtr does not rebind to _NodePtr.");
 };
 
-
-
 template 
 struct __hash_node_types_from_iterator;
 template 
@@ -258,29 +288,23 @@
 class _LIBCPP_TYPE_VIS_ONLY __hash_iterator
 {
 typedef __hash_node_types<_NodePtr> _NodeTypes;
-typedef _NodePtr__node_pointer;
+typedef _NodePtr__node_pointer;
+typedef typename _NodeTypes::__next_pointer __next_pointer;
 
-__node_pointer__node_;
+__next_pointer__node_;
 
 public:
 typedef forward_iterator_tag   iterator_category;
 typedef typename _NodeTypes::__node_value_type value_type;
 typedef typename _NodeTypes::difference_type   difference_type;
 typedef value_type&reference;
 typedef typename _NodeTypes::__node_value_type_pointer pointer;
 
-_LIBCPP_INLINE_VISIBILITY __hash_iterator() _NOEXCEPT
-#if _LIBCP

[libcxx] r276533 - Fix undefined behavior in __hash_table

2016-07-23 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Jul 23 15:36:55 2016
New Revision: 276533

URL: http://llvm.org/viewvc/llvm-project?rev=276533&view=rev
Log:
Fix undefined behavior in __hash_table

Summary:
This patch attempts to fix the undefined behavior in __hash_table by changing 
the node pointer types used throughout. The pointer types are changed for raw 
pointers in the current ABI and for fancy pointers in ABI V2 (since the fancy 
pointer types may not be ABI compatible).

The UB in `__hash_table` arises because tree downcasts the embedded end node 
and then deferences that pointer. Currently there are 2 node types in 
__hash_table:

* `__hash_node_base` which contains the `__next_` pointer.
* `__hash_node` which contains `__hash_` and `__value_`.

Currently the bucket list, iterators, and `__next_` pointers store pointers to 
`__hash_node` even though they all need to store `__hash_node_base` pointers.
This patch makes that change by introducing a `__next_pointer` typedef which is 
a pointer to `__hash_node` in the current ABI and `__hash_node_base` afterwards.

One notable change is to the type of `__bucket_list` which used to be defined 
as `unique_ptr<__node_pointer[], ...>` and is now `unique_ptr<__next_pointer[], 
...>` meaning that we now allocate and deallocate different types using a 
different allocator. I'm going to give this part of the change more thought 
since it may introduce compatibility issues.

This change is similar to D20786.



Reviewers: mclow.lists, EricWF

Subscribers: cfe-commits

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

Removed:
libcxx/trunk/test/ubsan_blacklist.txt
Modified:
libcxx/trunk/include/__config
libcxx/trunk/include/__debug
libcxx/trunk/include/__hash_table
libcxx/trunk/test/libcxx/test/config.py

Modified: libcxx/trunk/include/__config
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__config?rev=276533&r1=276532&r2=276533&view=diff
==
--- libcxx/trunk/include/__config (original)
+++ libcxx/trunk/include/__config Sat Jul 23 15:36:55 2016
@@ -43,6 +43,8 @@
 #define _LIBCPP_ABI_LIST_REMOVE_NODE_POINTER_UB
 // Fix undefined behavior in  how __tree stores its end and parent nodes.
 #define _LIBCPP_ABI_TREE_REMOVE_NODE_POINTER_UB
+// Fix undefined behavior in how __hash_table stores it's pointer types
+#define _LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB
 #define _LIBCPP_ABI_FORWARD_LIST_REMOVE_NODE_POINTER_UB
 #define _LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE
 #define _LIBCPP_ABI_VARIADIC_LOCK_GUARD

Modified: libcxx/trunk/include/__debug
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__debug?rev=276533&r1=276532&r2=276533&view=diff
==
--- libcxx/trunk/include/__debug (original)
+++ libcxx/trunk/include/__debug Sat Jul 23 15:36:55 2016
@@ -26,9 +26,22 @@
 #   endif
 #endif
 
+#if _LIBCPP_DEBUG_LEVEL >= 2
+#ifndef _LIBCPP_DEBUG_ASSERT
+#define _LIBCPP_DEBUG_ASSERT(x, m) _LIBCPP_ASSERT(x, m)
+#endif
+#define _LIBCPP_DEBUG_MODE(...) __VA_ARGS__
+#endif
+
 #ifndef _LIBCPP_ASSERT
 #   define _LIBCPP_ASSERT(x, m) ((void)0)
 #endif
+#ifndef _LIBCPP_DEBUG_ASSERT
+#   define _LIBCPP_DEBUG_ASSERT(x, m) ((void)0)
+#endif
+#ifndef _LIBCPP_DEBUG_MODE
+#define _LIBCPP_DEBUG_MODE(...) ((void)0)
+#endif
 
 #if _LIBCPP_DEBUG_LEVEL >= 2
 

Modified: libcxx/trunk/include/__hash_table
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__hash_table?rev=276533&r1=276532&r2=276533&view=diff
==
--- libcxx/trunk/include/__hash_table (original)
+++ libcxx/trunk/include/__hash_table Sat Jul 23 15:36:55 2016
@@ -59,9 +59,38 @@ size_t __next_prime(size_t __n);
 template 
 struct __hash_node_base
 {
+typedef typename pointer_traits<_NodePtr>::element_type __node_type;
 typedef __hash_node_base __first_node;
+typedef typename __rebind_pointer<_NodePtr, __first_node>::type 
__node_base_pointer;
+typedef _NodePtr __node_pointer;
+
+#if defined(_LIBCPP_ABI_FIX_UNORDERED_NODE_POINTER_UB)
+  typedef __node_base_pointer __next_pointer;
+#else
+  typedef typename conditional<
+  is_pointer<__node_pointer>::value,
+  __node_base_pointer,
+  __node_pointer>::type   __next_pointer;
+#endif
 
-_NodePtr__next_;
+__next_pointer__next_;
+
+_LIBCPP_INLINE_VISIBILITY
+__next_pointer __ptr() _NOEXCEPT {
+return static_cast<__next_pointer>(
+pointer_traits<__node_base_pointer>::pointer_to(*this));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+__node_pointer __upcast() _NOEXCEPT {
+return static_cast<__node_pointer>(
+pointer_traits<__node_base_pointer>::pointer_to(*this));
+}
+
+_LIBCPP_INLINE_VISIBILITY
+size_t __hash() const _NOEXCEPT {
+return static_cast<__node_type const&>(*this).__hash_;
+}
 
 _LIBCPP_INLINE_VIS

Re: [PATCH] D22622: [analyzer] Add more info to exploded graph dumps

2016-07-23 Thread Anna Zaks via cfe-commits
zaks.anna accepted this revision.
zaks.anna added a comment.
This revision is now accepted and ready to land.

> Yeah, just since we're all here anyway... By the way, -analyzer-config 
> prune-paths=false is also very handy.


I think you should add these to the checker writer manual in the debugging 
section.


https://reviews.llvm.org/D22622



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


Re: [PATCH] D20811: [analyzer] Model some library functions

2016-07-23 Thread Anna Zaks via cfe-commits
zaks.anna added inline comments.


Comment at: lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:191
@@ +190,3 @@
+// impossible to verify this precisely, but at least
+// this check avoids potential crashes.
+bool matchesCall(const CallExpr *CE) const;

Do we need to talk about crashes when describing what this does?
Also, please, use oxygen throughout.


Comment at: lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:205
@@ +204,3 @@
+  }
+  static QualType getArgType(const CallEvent &Call, ArgNoTy ArgNo) {
+return ArgNo == Ret ? Call.getResultType().getCanonicalType()

We could either provide these APIs in CallEvent or at least have variants that 
return canonical types. Maybe we already do some of that?


Comment at: lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:445
@@ +444,3 @@
+
+  const FunctionSpecTy &Spec = FSMI->second;
+  if (!Spec.matchesCall(CE))

When can this go wrong? Are we checking if there is a mismatch between the 
function declaration and the call expression? It is strange that 
findFunctionSpec takes both of those. Couldn't you always get FunctionDecl out 
of CallExpr?


Comment at: lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp:508
@@ +507,3 @@
+  FunctionSpecMap = {
+// The isascii() family of functions.
+{ "isalnum",

you could also use /*NameOfTheField*/ convention to name the arguments if that 
would make this map more readable.


Comment at: test/Analysis/std-library-functions.c:3
@@ +2,3 @@
+
+void clang_analyzer_eval(int);
+int glob;

Why are you not testing all of the functions?


https://reviews.llvm.org/D20811



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


[libcxx] r276537 - Implement the in_place tags from p0032r3.

2016-07-23 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Jul 23 17:19:19 2016
New Revision: 276537

URL: http://llvm.org/viewvc/llvm-project?rev=276537&view=rev
Log:
Implement the in_place tags from p0032r3.

That paper also has changes to any/optional but those will
be implemented later.


Added:
libcxx/trunk/test/std/utilities/utility/utility.inplace/
libcxx/trunk/test/std/utilities/utility/utility.inplace/inplace.pass.cpp
Modified:
libcxx/trunk/include/utility

Modified: libcxx/trunk/include/utility
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?rev=276537&r1=276536&r2=276537&view=diff
==
--- libcxx/trunk/include/utility (original)
+++ libcxx/trunk/include/utility Sat Jul 23 17:19:19 2016
@@ -171,6 +171,20 @@ template
 
 template
 T exchange(T& obj, U&& new_value);
+
+// 20.2.7, in-place construction // C++17
+struct in_place_tag { in_place_tag() = delete; }; // C++17
+using in_place_t = in_place_tag(&)(unspecified );
+template 
+using in_place_type_t = in_place_tag(&)(unspecified );
+template 
+using in_place_index_t = in_place_tag(&)(unspecified );
+in_place_tag in_place(unspecified );
+template 
+in_place_tag in_place(unspecified );
+template 
+in_place_tag in_place(unspecified );
+
 }  // std
 
 */
@@ -179,6 +193,7 @@ template
 #include <__tuple>
 #include 
 #include 
+#include <__debug>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #pragma GCC system_header
@@ -782,6 +797,49 @@ _T1 exchange(_T1& __obj, _T2 && __new_va
 }
 #endif  // _LIBCPP_STD_VER > 11
 
+#if _LIBCPP_STD_VER > 14
+
+struct _LIBCPP_TYPE_VIS_ONLY __in_place_tag {};
+template  struct _LIBCPP_TYPE_VIS_ONLY __in_place_type_tag {};
+template  struct _LIBCPP_TYPE_VIS_ONLY __in_place_index_tag {};
+
+struct _LIBCPP_TYPE_VIS_ONLY in_place_tag;
+
+using in_place_t = in_place_tag(&)(__in_place_tag);
+template 
+using in_place_type_t = in_place_tag(&)(__in_place_type_tag<_Tp>);
+template 
+using in_place_index_t = in_place_tag(&)(__in_place_index_tag<_Nx>);
+
+struct in_place_tag {
+  in_place_tag() = delete;
+private:
+  explicit in_place_tag(__in_place_tag) {}
+
+  friend inline in_place_tag in_place(__in_place_tag __t);
+  template 
+  friend inline in_place_tag in_place(__in_place_type_tag<_Tp>);
+  template 
+  friend inline in_place_tag in_place(__in_place_index_tag<_Nx>);
+};
+
+inline in_place_tag in_place(__in_place_tag __t) {
+_LIBCPP_ASSERT(false, "The in_place function cannot be invoked");
+return in_place_tag(__t);
+}
+template 
+inline in_place_tag in_place(__in_place_type_tag<_Tp>) {
+_LIBCPP_ASSERT(false, "The in_place function cannot be invoked");
+return in_place_tag(__in_place_tag{});
+}
+template 
+inline in_place_tag in_place(__in_place_index_tag<_Nx>) {
+_LIBCPP_ASSERT(false, "The in_place function cannot be invoked");
+return in_place_tag(__in_place_tag{});
+}
+
+#endif // _LIBCPP_STD_VER > 14
+
 _LIBCPP_END_NAMESPACE_STD
 
 #endif  // _LIBCPP_UTILITY

Added: libcxx/trunk/test/std/utilities/utility/utility.inplace/inplace.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/utility/utility.inplace/inplace.pass.cpp?rev=276537&view=auto
==
--- libcxx/trunk/test/std/utilities/utility/utility.inplace/inplace.pass.cpp 
(added)
+++ libcxx/trunk/test/std/utilities/utility/utility.inplace/inplace.pass.cpp 
Sat Jul 23 17:19:19 2016
@@ -0,0 +1,99 @@
+//===--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is dual licensed under the MIT and the University of Illinois Open
+// Source Licenses. See LICENSE.TXT for details.
+//
+//===--===//
+
+// UNSUPPORTED: c++98, c++03, c++11, c++14
+
+// 
+
+// struct in_place_tag { in_place_tag() = delete; };
+//
+// using in_place_t = in_place_tag(&)(unspecified);
+// template 
+// using in_place_type_t = in_place_tag(&)(unspecified);
+// template 
+// using in_place_index_t = in_place_tag(&)(unspecified);
+//
+// in_place_tag in_place(unspecified);
+//
+// template ;
+// in_place_tag in_place(unspecified);
+//
+// template 
+// in_place_tag in_place(unspecified);
+
+#include 
+#include 
+#include 
+
+#include "test_macros.h"
+#include "type_id.h"
+
+template 
+struct CheckRet : std::false_type {};
+template 
+struct CheckRet : std::true_type {};
+
+TypeID const* test_fn(std::in_place_t) { return 
&makeTypeID(); }
+template 
+TypeID const* test_fn(std::in_place_type_t)
+{ return &makeTypeID>(); }
+
+template 
+TypeID const* test_fn(std::in_place_index_t)
+{ return &makeTypeID>(); }
+
+// Concrete test overloads that don't have to be deduced.
+template 
+TypeID const* concrete_test_fn(Tag) {  return &makeTypeID(); }
+
+template 
+bool check_tag_basic() {
+  using RawTp = typename std:

[libcxx] r276544 - Implement P0040r3: Extending memory management tools

2016-07-23 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Jul 23 22:51:39 2016
New Revision: 276544

URL: http://llvm.org/viewvc/llvm-project?rev=276544&view=rev
Log:
Implement P0040r3: Extending memory management tools

Added:

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy.pass.cpp

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_n.pass.cpp

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct.pass.cpp

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.default/uninitialized_default_construct_n.pass.cpp

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct.pass.cpp

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.construct.value/uninitialized_value_construct_n.pass.cpp

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move.pass.cpp

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/uninitialized.move/uninitialized_move_n.pass.cpp
libcxx/trunk/test/support/test_throw.h
Modified:
libcxx/trunk/include/memory
libcxx/trunk/www/cxx1z_status.html

Modified: libcxx/trunk/include/memory
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/memory?rev=276544&r1=276543&r2=276544&view=diff
==
--- libcxx/trunk/include/memory (original)
+++ libcxx/trunk/include/memory Sat Jul 23 22:51:39 2016
@@ -180,6 +180,33 @@ template 
+void destroy_at(T* location);
+
+template 
+ void destroy(ForwardIterator first, ForwardIterator last);
+
+template 
+ ForwardIterator destroy_n(ForwardIterator first, Size n);
+
+template 
+ ForwardIterator uninitialized_move(InputIterator first, InputIterator last, 
ForwardIterator result);
+
+template 
+ pair uninitialized_move_n(InputIterator first, 
Size n, ForwardIterator result);
+
+template 
+ void uninitialized_value_construct(ForwardIterator first, ForwardIterator 
last);
+
+template 
+ ForwardIterator uninitialized_value_construct_n(ForwardIterator first, Size 
n);
+
+template 
+ void uninitialized_default_construct(ForwardIterator first, ForwardIterator 
last);
+
+template 
+ ForwardIterator uninitialized_default_construct_n(ForwardIterator first, Size 
n);
+
 template  struct auto_ptr_ref {};
 
 template
@@ -3671,6 +3698,87 @@ uninitialized_fill_n(_ForwardIterator __
 return __f;
 }
 
+#if _LIBCPP_STD_VER > 14
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY
+void uninitialized_default_construct(_ForwardIterator __first, 
_ForwardIterator __last) {
+using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
+for (; __first != __last; ++__first)
+::new((void*)_VSTD::addressof(*__first)) _Vt;
+}
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator uninitialized_default_construct_n(_ForwardIterator __first, 
_Size __n) {
+using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
+for (; __n > 0; (void)++__first, --__n)
+::new((void*)_VSTD::addressof(*__first)) _Vt;
+return __first;
+}
+
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY
+void uninitialized_value_construct(_ForwardIterator __first, _ForwardIterator 
__last) {
+using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
+for (; __first != __last; ++__first)
+::new((void*)_VSTD::addressof(*__first)) _Vt();
+}
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIterator uninitialized_value_construct_n(_ForwardIterator __first, 
_Size __n) {
+using _Vt = typename iterator_traits<_ForwardIterator>::value_type;
+for (; __n > 0; (void)++__first, --__n)
+::new((void*)_VSTD::addressof(*__first)) _Vt();
+return __first;
+}
+
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY
+_ForwardIt uninitialized_move(_InputIt __first, _InputIt __last, _ForwardIt 
__res) {
+using _Vt = typename iterator_traits<_ForwardIt>::value_type;
+for (; __first != __last; (void)++__res, ++__first)
+::new((void*)_VSTD::addressof(*__res)) _Vt(std::move(*__first));
+return __res;
+}
+
+template 
+inline _LIBCPP_INLINE_VISIBILITY
+pair<_InputIt, _ForwardIt>
+uninitialized_move_n(_InputIt __first, _Size __n, _ForwardIt __res) {
+using _Vt = typename iterator_traits<_ForwardIt>::value_type;
+for (; __n > 0; ++__res, (void

[libcxx] r276545 - Implement LWG2328. Rvalue stream extraction should perfect forward.

2016-07-23 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Jul 23 23:07:22 2016
New Revision: 276545

URL: http://llvm.org/viewvc/llvm-project?rev=276545&view=rev
Log:
Implement LWG2328. Rvalue stream extraction should perfect forward.

Modified:
libcxx/trunk/include/istream

libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.rvalue/rvalue.pass.cpp
libcxx/trunk/www/cxx1z_status.html

Modified: libcxx/trunk/include/istream
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/istream?rev=276545&r1=276544&r2=276545&view=diff
==
--- libcxx/trunk/include/istream (original)
+++ libcxx/trunk/include/istream Sat Jul 23 23:07:22 2016
@@ -1481,9 +1481,9 @@ ws(basic_istream<_CharT, _Traits>& __is)
 template 
 inline _LIBCPP_INLINE_VISIBILITY
 basic_istream<_CharT, _Traits>&
-operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x)
+operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp&& __x)
 {
-__is >> __x;
+__is >> _VSTD::forward<_Tp>(__x);
 return __is;
 }
 

Modified: 
libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.rvalue/rvalue.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.rvalue/rvalue.pass.cpp?rev=276545&r1=276544&r2=276545&view=diff
==
--- 
libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.rvalue/rvalue.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/input.output/iostream.format/input.streams/istream.rvalue/rvalue.pass.cpp
 Sat Jul 23 23:07:22 2016
@@ -7,17 +7,18 @@
 //
 
//===--===//
 
+// UNSUPPORTED: c++98, c++03
+
 // 
 
 // template 
 //   basic_istream&
-//   operator>>(basic_istream&& is, T& x);
+//   operator>>(basic_istream&& is, T&& x);
 
 #include 
+#include 
 #include 
 
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
-
 template 
 struct testbuf
 : public std::basic_streambuf
@@ -42,11 +43,13 @@ public:
 CharT* egptr() const {return base::egptr();}
 };
 
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+
+struct A{};
+bool called = false;
+void operator>>(std::istream&, A&&){ called = true; }
 
 int main()
 {
-#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
 {
 testbuf sb("   123");
 int i = 0;
@@ -59,5 +62,11 @@ int main()
 std::wistream(&sb) >> i;
 assert(i == 123);
 }
-#endif  // _LIBCPP_HAS_NO_RVALUE_REFERENCES
+{ // test perfect forwarding
+assert(called == false);
+std::istringstream ss;
+auto& out = (std::move(ss) >> A{});
+assert(&out == &ss);
+assert(called);
+}
 }

Modified: libcxx/trunk/www/cxx1z_status.html
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/www/cxx1z_status.html?rev=276545&r1=276544&r2=276545&view=diff
==
--- libcxx/trunk/www/cxx1z_status.html (original)
+++ libcxx/trunk/www/cxx1z_status.html Sat Jul 23 23:07:22 2016
@@ -264,7 +264,7 @@
http://wg21.link/LWG2309";>2309mutex::lock() should not throw 
device_or_resource_busyOuluComplete
http://wg21.link/LWG2310";>2310Public 
exposition only member in std::arrayOuluComplete
http://wg21.link/LWG2312";>2312tuple's 
constructor constraints need to be phrased more 
preciselyOuluComplete
-   http://wg21.link/LWG2328";>2328Rvalue 
stream extraction should use perfect forwardingOulu
+   http://wg21.link/LWG2328";>2328Rvalue 
stream extraction should use perfect 
forwardingOuluComplete
http://wg21.link/LWG2393";>2393std::function's Callable 
definition is brokenOulu
http://wg21.link/LWG2422";>2422std::numeric_limits::is_modulo
 description: "most machines" errataOuluComplete
http://wg21.link/LWG2426";>2426Issue about 
compare_exchangeOulu


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


[libcxx] r276546 - Implement LWG 2393. Check for LValue-callability.

2016-07-23 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Jul 23 23:16:40 2016
New Revision: 276546

URL: http://llvm.org/viewvc/llvm-project?rev=276546&view=rev
Log:
Implement LWG 2393. Check for LValue-callability.

Modified:

libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp

libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp

libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
libcxx/trunk/www/cxx1z_status.html

Modified: 
libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp?rev=276546&r1=276545&r2=276546&view=diff
==
--- 
libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F.pass.cpp
 Sat Jul 23 23:16:40 2016
@@ -16,6 +16,7 @@
 #include 
 #include 
 
+#include "test_macros.h"
 #include "count_new.hpp"
 
 class A
@@ -49,6 +50,17 @@ int A::count = 0;
 
 int g(int) {return 0;}
 
+#if TEST_STD_VER >= 11
+struct RValueCallable {
+template 
+void operator()(Args&&...) && {}
+};
+struct LValueCallable {
+template 
+void operator()(Args&&...) & {}
+};
+#endif
+
 int main()
 {
 assert(globalMemCounter.checkOutstandingNewEq(0));
@@ -91,4 +103,13 @@ int main()
 std::function  f(static_cast(0));
 assert(!f);
 }
+#if TEST_STD_VER >= 11
+{
+using Fn = std::function;
+static_assert(std::is_constructible::value, "");
+static_assert(std::is_constructible::value, "");
+static_assert(!std::is_constructible::value, "");
+static_assert(!std::is_constructible::value, "");
+}
+#endif
 }

Modified: 
libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp?rev=276546&r1=276545&r2=276546&view=diff
==
--- 
libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/F_assign.pass.cpp
 Sat Jul 23 23:16:40 2016
@@ -19,6 +19,7 @@
 #include 
 #include 
 
+#include "test_macros.h"
 #include "count_new.hpp"
 
 class A
@@ -52,6 +53,17 @@ int A::count = 0;
 
 int g(int) {return 0;}
 
+#if TEST_STD_VER >= 11
+struct RValueCallable {
+template 
+void operator()(Args&&...) && {}
+};
+struct LValueCallable {
+template 
+void operator()(Args&&...) & {}
+};
+#endif
+
 int main()
 {
 assert(globalMemCounter.checkOutstandingNewEq(0));
@@ -95,4 +107,13 @@ int main()
 assert(f.target() != 0);
 f(1);
 }
+#if TEST_STD_VER >= 11
+{
+using Fn = std::function;
+static_assert(std::is_assignable::value, "");
+static_assert(std::is_assignable::value, "");
+static_assert(!std::is_assignable::value, "");
+static_assert(!std::is_assignable::value, "");
+}
+#endif
 }

Modified: 
libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp?rev=276546&r1=276545&r2=276546&view=diff
==
--- 
libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/utilities/function.objects/func.wrap/func.wrap.func/func.wrap.func.con/alloc_F.pass.cpp
 Sat Jul 23 23:16:40 2016
@@ -16,11 +16,24 @@
 #include 
 #include 
 
+#include "test_macros.h"
 #include "min_allocator.h"
 #include "test_allocator.h"
 #include "count_new.hpp"
 #include "../function_types.h"
 
+
+#if TEST_STD_VER >= 11
+struct RValueCallable {
+template 
+void operator()(Args&&...) && {}
+};
+struct LValueCallable {
+template 
+void operator()(Args&&...) & {}
+};
+#endif
+
 class DummyClass {};
 
 template 
@@ -103,4 +116,14 @@ int main()
 non_default_test_allocator non_default_alloc(42);
 test_for_alloc(non_default_alloc);
 }
+#if TEST_STD_VER >= 11
+{
+using Fn = std::function;
+static_assert(std::is_constructible, LValueCallable&>::value, "");
+static_assert(std::is_constructible, LValueCallable>::value, "")

[libcxx] r276547 - Fix memory leak in test.

2016-07-23 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sat Jul 23 23:41:44 2016
New Revision: 276547

URL: http://llvm.org/viewvc/llvm-project?rev=276547&view=rev
Log:
Fix memory leak in test.

Modified:

libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp

Modified: 
libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp?rev=276547&r1=276546&r2=276547&view=diff
==
--- 
libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp
 (original)
+++ 
libcxx/trunk/test/std/utilities/memory/specialized.algorithms/specialized.destroy/destroy_at.pass.cpp
 Sat Jul 23 23:41:44 2016
@@ -56,6 +56,8 @@ int main()
 assert(Counted::count == 1);
 std::destroy_at(ptr2);
 assert(Counted::count == 0);
+std::free(mem1);
+std::free(mem2);
 }
 {
 void* mem1 = std::malloc(sizeof(DCounted));
@@ -70,5 +72,7 @@ int main()
 assert(VCounted::count == 1);
 std::destroy_at(ptr2);
 assert(VCounted::count == 0);
+std::free(mem1);
+std::free(mem2);
 }
 }


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


[libcxx] r276548 - Make pair/tuples assignment operators SFINAE properly.

2016-07-23 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sun Jul 24 00:51:11 2016
New Revision: 276548

URL: http://llvm.org/viewvc/llvm-project?rev=276548&view=rev
Log:
Make pair/tuples assignment operators SFINAE properly.


Added:

libcxx/trunk/test/std/utilities/utility/pairs/pairs.pair/assign_pair.pass.cpp
Modified:
libcxx/trunk/include/tuple
libcxx/trunk/include/utility
libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp
libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.assign/move.pass.cpp

libcxx/trunk/test/std/utilities/utility/pairs/pairs.pair/assign_rv_pair.pass.cpp

Modified: libcxx/trunk/include/tuple
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/tuple?rev=276548&r1=276547&r2=276548&view=diff
==
--- libcxx/trunk/include/tuple (original)
+++ libcxx/trunk/include/tuple Sun Jul 24 00:51:11 2016
@@ -647,6 +647,9 @@ public:
 _LIBCPP_CONSTEXPR tuple()
 
_NOEXCEPT_(__all::value...>::value) {}
 
+tuple(tuple const&) = default;
+tuple(tuple&&) = default;
+
 template ,
@@ -885,6 +888,25 @@ public:
 tuple(allocator_arg_t, const _Alloc& __a, _Tuple&& __t)
 : base_(allocator_arg_t(), __a, _VSTD::forward<_Tuple>(__t)) {}
 
+using _CanCopyAssign = __all::value...>;
+using _CanMoveAssign = __all::value...>;
+
+_LIBCPP_INLINE_VISIBILITY
+tuple& operator=(typename conditional<_CanCopyAssign::value, tuple, 
__nat>::type const& __t)
+_NOEXCEPT_((__all::value...>::value))
+{
+base_.operator=(__t.base_);
+return *this;
+}
+
+_LIBCPP_INLINE_VISIBILITY
+tuple& operator=(typename conditional<_CanMoveAssign::value, tuple, 
__nat>::type&& __t)
+_NOEXCEPT_((__all::value...>::value))
+{
+base_.operator=(static_cast(__t.base_));
+return *this;
+}
+
 template http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/utility?rev=276548&r1=276547&r2=276548&view=diff
==
--- libcxx/trunk/include/utility (original)
+++ libcxx/trunk/include/utility Sun Jul 24 00:51:11 2016
@@ -348,8 +348,15 @@ struct _LIBCPP_TYPE_VIS_ONLY pair
   // Use the implicitly declared copy constructor in C++03
 #endif
 
+typedef typename remove_reference<_T1>::type _T1Unref;
+typedef typename remove_reference<_T2>::type _T2Unref;
+
+typedef integral_constant::value
+&& is_copy_assignable<_T2>::value> _CanCopyAssign;
+
 _LIBCPP_INLINE_VISIBILITY
-pair& operator=(const pair& __p)
+pair& operator=(typename conditional<_CanCopyAssign::value, pair, 
__nat>::type const& __p)
 _NOEXCEPT_(is_nothrow_copy_assignable::value &&
is_nothrow_copy_assignable::value)
 {
@@ -377,10 +384,15 @@ struct _LIBCPP_TYPE_VIS_ONLY pair
 : first(_VSTD::forward<_U1>(__p.first)),
   second(_VSTD::forward<_U2>(__p.second)) {}
 
+typedef integral_constant::value
+&& is_move_assignable<_T2>::value> _CanMoveAssign;
+
 _LIBCPP_INLINE_VISIBILITY
 pair&
-operator=(pair&& __p) 
_NOEXCEPT_(is_nothrow_move_assignable::value &&
- 
is_nothrow_move_assignable::value)
+operator=(typename conditional<_CanMoveAssign::value, pair, __nat>::type&& 
__p)
+_NOEXCEPT_(is_nothrow_move_assignable::value &&
+   is_nothrow_move_assignable::value)
 {
 first = _VSTD::forward(__p.first);
 second = _VSTD::forward(__p.second);
@@ -388,7 +400,6 @@ struct _LIBCPP_TYPE_VIS_ONLY pair
 }
 
 #ifndef _LIBCPP_HAS_NO_VARIADICS
-
 template::value>::type>
 _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11
@@ -411,7 +422,7 @@ struct _LIBCPP_TYPE_VIS_ONLY pair
 {}
 
 template ::value>::type>
+  class = typename enable_if::type, pair>::value && __tuple_assignable<_Tuple, 
pair>::value>::type>
 _LIBCPP_INLINE_VISIBILITY
 pair&
 operator=(_Tuple&& __p)

Modified: 
libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp?rev=276548&r1=276547&r2=276548&view=diff
==
--- 
libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp 
(original)
+++ 
libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.assign/copy.pass.cpp 
Sun Jul 24 00:51:11 2016
@@ -19,6 +19,22 @@
 #include 
 #include 
 
+#include "test_macros.h"
+
+struct NonAssignable {
+  NonAssignable& operator=(NonAssignable const&) = delete;
+  NonAssignable& operator=(NonAssignable&&) = delete;
+};
+struct CopyAssignable {
+  CopyAssignable& operator=(CopyAssignable const&) = default;
+  CopyAssignable& operator=(CopyAssignable &&) = delete;
+};
+static_assert(std:

Re: [PATCH] D21314: Make pair and tuple respect is_copy_assignable and is_move_assignable

2016-07-23 Thread Eric Fiselier via cfe-commits
EricWF abandoned this revision.
EricWF added a comment.

Similar reversion committed as r276548.


https://reviews.llvm.org/D21314



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


[libcxx] r276549 - Skip chash computation in insert/emplace if the unconstrained hash matches.

2016-07-23 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sun Jul 24 01:22:25 2016
New Revision: 276549

URL: http://llvm.org/viewvc/llvm-project?rev=276549&view=rev
Log:
Skip chash computation in insert/emplace if the unconstrained hash matches.


Modified:
libcxx/trunk/benchmarks/ContainerBenchmarks.hpp
libcxx/trunk/benchmarks/GenerateInput.hpp
libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp
libcxx/trunk/include/__hash_table

Modified: libcxx/trunk/benchmarks/ContainerBenchmarks.hpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/ContainerBenchmarks.hpp?rev=276549&r1=276548&r2=276549&view=diff
==
--- libcxx/trunk/benchmarks/ContainerBenchmarks.hpp (original)
+++ libcxx/trunk/benchmarks/ContainerBenchmarks.hpp Sun Jul 24 01:22:25 2016
@@ -34,6 +34,38 @@ void BM_InsertValueRehash(benchmark::Sta
 }
 }
 
+
+template 
+void BM_InsertDuplicate(benchmark::State& st, Container c, GenInputs gen) {
+auto in = gen(st.range_x());
+const auto end = in.end();
+c.insert(in.begin(), in.end());
+benchmark::DoNotOptimize(&c);
+benchmark::DoNotOptimize(&in);
+while (st.KeepRunning()) {
+for (auto it = in.begin(); it != end; ++it) {
+benchmark::DoNotOptimize(&(*c.insert(*it).first));
+}
+benchmark::ClobberMemory();
+}
+}
+
+
+template 
+void BM_EmplaceDuplicate(benchmark::State& st, Container c, GenInputs gen) {
+auto in = gen(st.range_x());
+const auto end = in.end();
+c.insert(in.begin(), in.end());
+benchmark::DoNotOptimize(&c);
+benchmark::DoNotOptimize(&in);
+while (st.KeepRunning()) {
+for (auto it = in.begin(); it != end; ++it) {
+benchmark::DoNotOptimize(&(*c.emplace(*it).first));
+}
+benchmark::ClobberMemory();
+}
+}
+
 template 
 static void BM_Find(benchmark::State& st, Container c, GenInputs gen) {
 auto in = gen(st.range_x());

Modified: libcxx/trunk/benchmarks/GenerateInput.hpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/GenerateInput.hpp?rev=276549&r1=276548&r2=276549&view=diff
==
--- libcxx/trunk/benchmarks/GenerateInput.hpp (original)
+++ libcxx/trunk/benchmarks/GenerateInput.hpp Sun Jul 24 01:22:25 2016
@@ -130,4 +130,11 @@ inline std::vector getRever
 return inputs;
 }
 
+inline std::vector getRandomCStringInputs(size_t N) {
+static std::vector inputs = getRandomStringInputs(N);
+std::vector cinputs;
+for (auto const& str : inputs)
+cinputs.push_back(str.c_str());
+return cinputs;
+}
 #endif // BENCHMARK_GENERATE_INPUT_HPP

Modified: libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp?rev=276549&r1=276548&r2=276549&view=diff
==
--- libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp (original)
+++ libcxx/trunk/benchmarks/unordered_set_operations.bench.cpp Sun Jul 24 
01:22:25 2016
@@ -265,4 +265,42 @@ BENCHMARK_CAPTURE(BM_FindRehash,
 std::unordered_set{},
 getRandomStringInputs)->Arg(TestNumInputs);
 
+///
+BENCHMARK_CAPTURE(BM_InsertDuplicate,
+unordered_set_int,
+std::unordered_set{},
+getRandomIntegerInputs)->Arg(TestNumInputs);
+BENCHMARK_CAPTURE(BM_InsertDuplicate,
+unordered_set_string,
+std::unordered_set{},
+getRandomStringInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
+unordered_set_int,
+std::unordered_set{},
+getRandomIntegerInputs)->Arg(TestNumInputs);
+BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
+unordered_set_string,
+std::unordered_set{},
+getRandomStringInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_InsertDuplicate,
+unordered_set_int_insert_arg,
+std::unordered_set{},
+getRandomIntegerInputs)->Arg(TestNumInputs);
+BENCHMARK_CAPTURE(BM_InsertDuplicate,
+unordered_set_string_insert_arg,
+std::unordered_set{},
+getRandomStringInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
+unordered_set_int_insert_arg,
+std::unordered_set{},
+getRandomIntegerInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
+unordered_set_string_arg,
+std::unordered_set{},
+getRandomCStringInputs)->Arg(TestNumInputs);
+
 BENCHMARK_MAIN()

Modified: libcxx/trunk/include/__hash_table
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/__hash_table?rev=276549&r1=276548&r2=276549&view=diff
==
--- libcxx/trunk/include/__hash_table (original)
+++ libcxx/trunk/include/__hash_table Sun Jul 24 01:22:25 2016
@@ -1961,7 +1961,7 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>
  

[libcxx] r276552 - Start adding benchmarks for vector

2016-07-23 Thread Eric Fiselier via cfe-commits
Author: ericwf
Date: Sun Jul 24 01:51:55 2016
New Revision: 276552

URL: http://llvm.org/viewvc/llvm-project?rev=276552&view=rev
Log:
Start adding benchmarks for vector

Added:
libcxx/trunk/benchmarks/vector_operations.bench.cpp
Modified:
libcxx/trunk/benchmarks/ContainerBenchmarks.hpp

Modified: libcxx/trunk/benchmarks/ContainerBenchmarks.hpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/ContainerBenchmarks.hpp?rev=276552&r1=276551&r2=276552&view=diff
==
--- libcxx/trunk/benchmarks/ContainerBenchmarks.hpp (original)
+++ libcxx/trunk/benchmarks/ContainerBenchmarks.hpp Sun Jul 24 01:51:55 2016
@@ -7,6 +7,18 @@
 
 namespace ContainerBenchmarks {
 
+
+template 
+void BM_ConstructIterIter(benchmark::State& st, Container, GenInputs gen) {
+auto in = gen(st.range_x());
+const auto end = in.end();
+benchmark::DoNotOptimize(&in);
+while (st.KeepRunning()) {
+Container c(in.begin(), in.end());
+benchmark::DoNotOptimize(c.data());
+}
+}
+
 template 
 void BM_InsertValue(benchmark::State& st, Container c, GenInputs gen) {
 auto in = gen(st.range_x());
@@ -93,7 +105,6 @@ static void BM_FindRehash(benchmark::Sta
 }
 benchmark::ClobberMemory();
 }
-
 }
 
 } // end namespace ContainerBenchmarks

Added: libcxx/trunk/benchmarks/vector_operations.bench.cpp
URL: 
http://llvm.org/viewvc/llvm-project/libcxx/trunk/benchmarks/vector_operations.bench.cpp?rev=276552&view=auto
==
--- libcxx/trunk/benchmarks/vector_operations.bench.cpp (added)
+++ libcxx/trunk/benchmarks/vector_operations.bench.cpp Sun Jul 24 01:51:55 2016
@@ -0,0 +1,32 @@
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "benchmark/benchmark_api.h"
+
+#include "ContainerBenchmarks.hpp"
+#include "GenerateInput.hpp"
+
+using namespace ContainerBenchmarks;
+
+constexpr std::size_t TestNumInputs = 1024;
+
+BENCHMARK_CAPTURE(BM_ConstructIterIter,
+  vector_char,
+  std::vector{},
+  getRandomIntegerInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_ConstructIterIter,
+  vector_size_t,
+  std::vector{},
+  getRandomIntegerInputs)->Arg(TestNumInputs);
+
+BENCHMARK_CAPTURE(BM_ConstructIterIter,
+  vector_string,
+  std::vector{},
+  getRandomStringInputs)->Arg(TestNumInputs);
+
+
+BENCHMARK_MAIN()


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