<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Reverted in <span style="font-family: Menlo; font-size: 11px;" class="">r275880</span>. Sorry about that. I’ll have to investigate why I didn’t get an email from the bot about the failure.<div class=""><br class=""></div><div class="">Thanks</div><div class="">Devin</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 18, 2016, at 11:59 AM, Hans Wennborg <<a href="mailto:hans@chromium.org" class="">hans@chromium.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="">Oops, as you suspected I failed at copy/paste. This is the bot that's<br class="">broken: <a href="http://bb.pgr.jp/builders/cmake-clang-x86_64-linux/builds/51780" class="">http://bb.pgr.jp/builders/cmake-clang-x86_64-linux/builds/51780</a><br class=""><br class="">On Mon, Jul 18, 2016 at 10:57 AM, Devin Coughlin <<a href="mailto:dcoughlin@apple.com" class="">dcoughlin@apple.com</a>> wrote:<br class=""><blockquote type="cite" class="">Hans,<br class=""><br class="">I’m happy to revert — but I think r275820 is very unlikely to have been the<br class="">root cause of the issue at<br class=""><a href="http://bb.pgr.jp/builders/cmake-llvm-x86_64-linux/builds/40225/" class="">http://bb.pgr.jp/builders/cmake-llvm-x86_64-linux/builds/40225/</a>. (The commit<br class="">is a change to the clang static analyzer and the bot failure seems to be in<br class="">LLVM CodeGen).<br class=""><br class="">Was this just a link mis-copy/paste? Is there another bot failing?<br class=""><br class="">Devin<br class=""><br class="">On Jul 18, 2016, at 10:50 AM, Hans Wennborg <<a href="mailto:hans@chromium.org" class="">hans@chromium.org</a>> wrote:<br class=""><br class="">It seems to have broken this buildbot:<br class=""><a href="http://bb.pgr.jp/builders/cmake-llvm-x86_64-linux/builds/40225/" class="">http://bb.pgr.jp/builders/cmake-llvm-x86_64-linux/builds/40225/</a><br class=""><br class="">I'm just about to create the 3.9 release branch, so it would be great<br class="">if this could fixed/figured out soon.<br class=""><br class="">Thanks,<br class="">Hans<br class=""><br class="">On Mon, Jul 18, 2016 at 10:23 AM, Devin Coughlin via cfe-commits<br class=""><cfe-commits@lists.llvm.org> wrote:<br class=""><br class="">Author: dcoughlin<br class="">Date: Mon Jul 18 12:23:30 2016<br class="">New Revision: 275820<br class=""><br class="">URL: http://llvm.org/viewvc/llvm-project?rev=275820&view=rev<br class="">Log:<br class="">[analyzer] Add checker modeling potential C++ self-assignment<br class=""><br class="">This checker checks copy and move assignment operators whether they are<br class="">protected against self-assignment. Since C++ core guidelines discourages<br class="">explicit checking for `&rhs==this` in general we take a different approach:<br class="">in<br class="">top-frame analysis we branch the exploded graph for two cases, where<br class="">&rhs==this<br class="">and &rhs!=this and let existing checkers (e.g. unix.Malloc) do the rest of<br class="">the<br class="">work. It is important that we check all copy and move assignment operator in<br class="">top<br class="">frame even if we checked them already since self-assignments may happen<br class="">undetected even in the same translation unit (e.g. using random indices for<br class="">an<br class="">array what may or may not be the same).<br class=""><br class="">A patch by Ádám Balogh!<br class=""><br class="">Differential Revision: https://reviews.llvm.org/D19311<br class=""><br class="">Added:<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp<br class="">   cfe/trunk/test/Analysis/self-assign.cpp<br class="">Modified:<br class="">   cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td<br class=""><br class="">cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt<br class="">   cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp<br class="">   cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp<br class="">   cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp<br class=""><br class="">Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=275820&r1=275819&r2=275820&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)<br class="">+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Mon Jul 18<br class="">12:23:30 2016<br class="">@@ -247,6 +247,10 @@ def NewDeleteLeaksChecker : Checker<"New<br class="">  HelpText<"Check for memory leaks. Traces memory managed by new/delete.">,<br class="">  DescFile<"MallocChecker.cpp">;<br class=""><br class="">+def CXXSelfAssignmentChecker : Checker<"SelfAssignment">,<br class="">+  HelpText<"Checks C++ copy and move assignment operators for self<br class="">assignment">,<br class="">+  DescFile<"CXXSelfAssignmentChecker.cpp">;<br class="">+<br class="">} // end: "cplusplus"<br class=""><br class="">let ParentPackage = CplusplusAlpha in {<br class=""><br class="">Modified:<br class="">cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h?rev=275820&r1=275819&r2=275820&view=diff<br class="">==============================================================================<br class="">---<br class="">cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h<br class="">(original)<br class="">+++<br class="">cfe/trunk/include/clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h<br class="">Mon Jul 18 12:23:30 2016<br class="">@@ -331,6 +331,22 @@ public:<br class="">                                 BugReport &BR) override;<br class="">};<br class=""><br class="">+class CXXSelfAssignmentBRVisitor final<br class="">+  : public BugReporterVisitorImpl<CXXSelfAssignmentBRVisitor> {<br class="">+<br class="">+  bool Satisfied;<br class="">+<br class="">+public:<br class="">+  CXXSelfAssignmentBRVisitor() : Satisfied(false) {}<br class="">+<br class="">+  void Profile(llvm::FoldingSetNodeID &ID) const override {}<br class="">+<br class="">+  PathDiagnosticPiece *VisitNode(const ExplodedNode *Succ,<br class="">+                                 const ExplodedNode *Pred,<br class="">+                                 BugReporterContext &BRC,<br class="">+                                 BugReport &BR) override;<br class="">+};<br class="">+<br class="">namespace bugreporter {<br class=""><br class="">/// Attempts to add visitors to trace a null or undefined value back to its<br class=""><br class="">Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt?rev=275820&r1=275819&r2=275820&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt (original)<br class="">+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt Mon Jul 18 12:23:30<br class="">2016<br class="">@@ -22,6 +22,7 @@ add_clang_library(clangStaticAnalyzerChe<br class="">  CheckerDocumentation.cpp<br class="">  ChrootChecker.cpp<br class="">  ClangCheckers.cpp<br class="">+  CXXSelfAssignmentChecker.cpp<br class="">  DeadStoresChecker.cpp<br class="">  DebugCheckers.cpp<br class="">  DereferenceChecker.cpp<br class=""><br class="">Added: cfe/trunk/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp?rev=275820&view=auto<br class="">==============================================================================<br class="">--- cfe/trunk/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp<br class="">(added)<br class="">+++ cfe/trunk/lib/StaticAnalyzer/Checkers/CXXSelfAssignmentChecker.cpp Mon<br class="">Jul 18 12:23:30 2016<br class="">@@ -0,0 +1,62 @@<br class="">+//=== CXXSelfAssignmentChecker.cpp -----------------------------*- C++<br class="">-*--===//<br class="">+//<br class="">+//                     The LLVM Compiler Infrastructure<br class="">+//<br class="">+// This file is distributed under the University of Illinois Open Source<br class="">+// License. See LICENSE.TXT for details.<br class="">+//<br class="">+//===----------------------------------------------------------------------===//<br class="">+//<br class="">+// This file defines CXXSelfAssignmentChecker, which tests all custom<br class="">defined<br class="">+// copy and move assignment operators for the case of self assignment, thus<br class="">+// where the parameter refers to the same location where the this pointer<br class="">+// points to. The checker itself does not do any checks at all, but it<br class="">+// causes the analyzer to check every copy and move assignment operator<br class="">twice:<br class="">+// once for when 'this' aliases with the parameter and once for when it may<br class="">not.<br class="">+// It is the task of the other enabled checkers to find the bugs in these<br class="">two<br class="">+// different cases.<br class="">+//<br class="">+//===----------------------------------------------------------------------===//<br class="">+<br class="">+#include "ClangSACheckers.h"<br class="">+#include "clang/StaticAnalyzer/Core/Checker.h"<br class="">+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"<br class="">+<br class="">+using namespace clang;<br class="">+using namespace ento;<br class="">+<br class="">+namespace {<br class="">+<br class="">+class CXXSelfAssignmentChecker : public Checker<check::BeginFunction> {<br class="">+public:<br class="">+  CXXSelfAssignmentChecker();<br class="">+  void checkBeginFunction(CheckerContext &C) const;<br class="">+};<br class="">+}<br class="">+<br class="">+CXXSelfAssignmentChecker::CXXSelfAssignmentChecker() {}<br class="">+<br class="">+void CXXSelfAssignmentChecker::checkBeginFunction(CheckerContext &C) const<br class="">{<br class="">+  if (!C.inTopFrame())<br class="">+    return;<br class="">+  const auto *LCtx = C.getLocationContext();<br class="">+  const auto *MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl());<br class="">+  if (!MD)<br class="">+    return;<br class="">+  if (!MD->isCopyAssignmentOperator() && !MD->isMoveAssignmentOperator())<br class="">+    return;<br class="">+  auto &State = C.getState();<br class="">+  auto &SVB = C.getSValBuilder();<br class="">+  auto ThisVal =<br class="">+      State->getSVal(SVB.getCXXThis(MD, LCtx->getCurrentStackFrame()));<br class="">+  auto Param = SVB.makeLoc(State->getRegion(MD->getParamDecl(0), LCtx));<br class="">+  auto ParamVal = State->getSVal(Param);<br class="">+  ProgramStateRef SelfAssignState = State->bindLoc(Param, ThisVal);<br class="">+  C.addTransition(SelfAssignState);<br class="">+  ProgramStateRef NonSelfAssignState = State->bindLoc(Param, ParamVal);<br class="">+  C.addTransition(NonSelfAssignState);<br class="">+}<br class="">+<br class="">+void ento::registerCXXSelfAssignmentChecker(CheckerManager &Mgr) {<br class="">+  Mgr.registerChecker<CXXSelfAssignmentChecker>();<br class="">+}<br class=""><br class="">Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp?rev=275820&r1=275819&r2=275820&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp (original)<br class="">+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporter.cpp Mon Jul 18 12:23:30<br class="">2016<br class="">@@ -3104,6 +3104,7 @@ bool GRBugReporter::generatePathDiagnost<br class="">    R->addVisitor(llvm::make_unique<NilReceiverBRVisitor>());<br class="">    R->addVisitor(llvm::make_unique<ConditionBRVisitor>());<br class=""><br class="">R->addVisitor(llvm::make_unique<LikelyFalsePositiveSuppressionBRVisitor>());<br class="">+    R->addVisitor(llvm::make_unique<CXXSelfAssignmentBRVisitor>());<br class=""><br class="">    BugReport::VisitorList visitors;<br class="">    unsigned origReportConfigToken, finalReportConfigToken;<br class=""><br class="">Modified: cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp?rev=275820&r1=275819&r2=275820&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (original)<br class="">+++ cfe/trunk/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp Mon Jul 18<br class="">12:23:30 2016<br class="">@@ -1693,3 +1693,53 @@ UndefOrNullArgVisitor::VisitNode(const E<br class="">  }<br class="">  return nullptr;<br class="">}<br class="">+<br class="">+PathDiagnosticPiece *<br class="">+CXXSelfAssignmentBRVisitor::VisitNode(const ExplodedNode *Succ,<br class="">+                                      const ExplodedNode *Pred,<br class="">+                                      BugReporterContext &BRC, BugReport<br class="">&BR) {<br class="">+  if (Satisfied)<br class="">+    return nullptr;<br class="">+<br class="">+  auto Edge = Succ->getLocation().getAs<BlockEdge>();<br class="">+  if (!Edge.hasValue())<br class="">+    return nullptr;<br class="">+<br class="">+  auto Tag = Edge->getTag();<br class="">+  if (!Tag)<br class="">+    return nullptr;<br class="">+<br class="">+  if (Tag->getTagDescription() != "cplusplus.SelfAssignment")<br class="">+    return nullptr;<br class="">+<br class="">+  Satisfied = true;<br class="">+<br class="">+  const auto *Met =<br class="">+      dyn_cast<CXXMethodDecl>(Succ->getCodeDecl().getAsFunction());<br class="">+  assert(Met && "Not a C++ method.");<br class="">+  assert((Met->isCopyAssignmentOperator() ||<br class="">Met->isMoveAssignmentOperator()) &&<br class="">+         "Not a copy/move assignment operator.");<br class="">+<br class="">+  const auto *LCtx = Edge->getLocationContext();<br class="">+<br class="">+  const auto &State = Succ->getState();<br class="">+  auto &SVB = State->getStateManager().getSValBuilder();<br class="">+<br class="">+  const auto Param =<br class="">+      State->getSVal(State->getRegion(Met->getParamDecl(0), LCtx));<br class="">+  const auto This =<br class="">+      State->getSVal(SVB.getCXXThis(Met, LCtx->getCurrentStackFrame()));<br class="">+<br class="">+  auto L = PathDiagnosticLocation::create(Met, BRC.getSourceManager());<br class="">+<br class="">+  if (!L.isValid() || !L.asLocation().isValid())<br class="">+    return nullptr;<br class="">+<br class="">+  const auto Msg = "Assuming " + Met->getParamDecl(0)->getName() +<br class="">+                   ((Param == This) ? " == " : " != ") + "*this";<br class="">+<br class="">+  auto *Piece = new PathDiagnosticEventPiece(L, Msg.str());<br class="">+  Piece->addRange(Met->getSourceRange());<br class="">+<br class="">+  return Piece;<br class="">+}<br class=""><br class="">Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp?rev=275820&r1=275819&r2=275820&view=diff<br class="">==============================================================================<br class="">--- cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp (original)<br class="">+++ cfe/trunk/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp Mon Jul 18<br class="">12:23:30 2016<br class="">@@ -431,6 +431,13 @@ static bool shouldSkipFunction(const Dec<br class="">  //   Count naming convention errors more aggressively.<br class="">  if (isa<ObjCMethodDecl>(D))<br class="">    return false;<br class="">+  // We also want to reanalyze all C++ copy and move assignment operators<br class="">to<br class="">+  // separately check the two cases where 'this' aliases with the parameter<br class="">and<br class="">+  // where it may not. (cplusplus.SelfAssignmentChecker)<br class="">+  if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {<br class="">+    if (MD->isCopyAssignmentOperator() || MD->isMoveAssignmentOperator())<br class="">+      return false;<br class="">+  }<br class=""><br class="">  // Otherwise, if we visited the function before, do not reanalyze it.<br class="">  return Visited.count(D);<br class="">@@ -442,9 +449,7 @@ AnalysisConsumer::getInliningModeForFunc<br class="">  // We want to reanalyze all ObjC methods as top level to report Retain<br class="">  // Count naming convention errors more aggressively. But we should tune<br class="">down<br class="">  // inlining when reanalyzing an already inlined function.<br class="">-  if (Visited.count(D)) {<br class="">-    assert(isa<ObjCMethodDecl>(D) &&<br class="">-           "We are only reanalyzing ObjCMethods.");<br class="">+  if (Visited.count(D) && isa<ObjCMethodDecl>(D)) {<br class="">    const ObjCMethodDecl *ObjCM = cast<ObjCMethodDecl>(D);<br class="">    if (ObjCM->getMethodFamily() != OMF_init)<br class="">      return ExprEngine::Inline_Minimal;<br class=""><br class="">Added: cfe/trunk/test/Analysis/self-assign.cpp<br class="">URL:<br class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/self-assign.cpp?rev=275820&view=auto<br class="">==============================================================================<br class="">--- cfe/trunk/test/Analysis/self-assign.cpp (added)<br class="">+++ cfe/trunk/test/Analysis/self-assign.cpp Mon Jul 18 12:23:30 2016<br class="">@@ -0,0 +1,89 @@<br class="">+// RUN: %clang_cc1 -std=c++11 -analyze<br class="">-analyzer-checker=core,cplusplus,unix.Malloc,debug.ExprInspection %s -verify<br class="">-analyzer-output=text<br class="">+<br class="">+extern "C" char *strdup(const char* s);<br class="">+extern "C" void free(void* ptr);<br class="">+<br class="">+namespace std {<br class="">+template<class T> struct remove_reference      { typedef T type; };<br class="">+template<class T> struct remove_reference<T&>  { typedef T type; };<br class="">+template<class T> struct remove_reference<T&&> { typedef T type; };<br class="">+template<class T> typename remove_reference<T>::type&& move(T&& t);<br class="">+}<br class="">+<br class="">+void clang_analyzer_eval(int);<br class="">+<br class="">+class StringUsed {<br class="">+public:<br class="">+  StringUsed(const char *s = "") : str(strdup(s)) {}<br class="">+  StringUsed(const StringUsed &rhs) : str(strdup(rhs.str)) {}<br class="">+  ~StringUsed();<br class="">+  StringUsed& operator=(const StringUsed &rhs);<br class="">+  StringUsed& operator=(StringUsed &&rhs);<br class="">+  operator const char*() const;<br class="">+private:<br class="">+  char *str;<br class="">+};<br class="">+<br class="">+StringUsed::~StringUsed() {<br class="">+  free(str);<br class="">+}<br class="">+<br class="">+StringUsed& StringUsed::operator=(const StringUsed &rhs) { //<br class="">expected-note{{Assuming rhs == *this}} expected-note{{Assuming rhs ==<br class="">*this}} expected-note{{Assuming rhs != *this}}<br class="">+  clang_analyzer_eval(*this == rhs); // expected-warning{{TRUE}}<br class="">expected-warning{{UNKNOWN}} expected-note{{TRUE}} expected-note{{UNKNOWN}}<br class="">+  free(str); // expected-note{{Memory is released}}<br class="">+  str = strdup(rhs.str); // expected-warning{{Use of memory after it is<br class="">freed}}  expected-note{{Use of memory after it is freed}}<br class="">+  return *this;<br class="">+}<br class="">+<br class="">+StringUsed& StringUsed::operator=(StringUsed &&rhs) { //<br class="">expected-note{{Assuming rhs == *this}} expected-note{{Assuming rhs !=<br class="">*this}}<br class="">+  clang_analyzer_eval(*this == rhs); // expected-warning{{TRUE}}<br class="">expected-warning{{UNKNOWN}} expected-note{{TRUE}} expected-note{{UNKNOWN}}<br class="">+  str = rhs.str;<br class="">+  rhs.str = nullptr; // FIXME: An improved leak checker should warn here<br class="">+  return *this;<br class="">+}<br class="">+<br class="">+StringUsed::operator const char*() const {<br class="">+  return str;<br class="">+}<br class="">+<br class="">+class StringUnused {<br class="">+public:<br class="">+  StringUnused(const char *s = "") : str(strdup(s)) {}<br class="">+  StringUnused(const StringUnused &rhs) : str(strdup(rhs.str)) {}<br class="">+  ~StringUnused();<br class="">+  StringUnused& operator=(const StringUnused &rhs);<br class="">+  StringUnused& operator=(StringUnused &&rhs);<br class="">+  operator const char*() const;<br class="">+private:<br class="">+  char *str;<br class="">+};<br class="">+<br class="">+StringUnused::~StringUnused() {<br class="">+  free(str);<br class="">+}<br class="">+<br class="">+StringUnused& StringUnused::operator=(const StringUnused &rhs) { //<br class="">expected-note{{Assuming rhs == *this}} expected-note{{Assuming rhs ==<br class="">*this}} expected-note{{Assuming rhs != *this}}<br class="">+  clang_analyzer_eval(*this == rhs); // expected-warning{{TRUE}}<br class="">expected-warning{{UNKNOWN}} expected-note{{TRUE}} expected-note{{UNKNOWN}}<br class="">+  free(str); // expected-note{{Memory is released}}<br class="">+  str = strdup(rhs.str); // expected-warning{{Use of memory after it is<br class="">freed}}  expected-note{{Use of memory after it is freed}}<br class="">+  return *this;<br class="">+}<br class="">+<br class="">+StringUnused& StringUnused::operator=(StringUnused &&rhs) { //<br class="">expected-note{{Assuming rhs == *this}} expected-note{{Assuming rhs !=<br class="">*this}}<br class="">+  clang_analyzer_eval(*this == rhs); // expected-warning{{TRUE}}<br class="">expected-warning{{UNKNOWN}} expected-note{{TRUE}} expected-note{{UNKNOWN}}<br class="">+  str = rhs.str;<br class="">+  rhs.str = nullptr; // FIXME: An improved leak checker should warn here<br class="">+  return *this;<br class="">+}<br class="">+<br class="">+StringUnused::operator const char*() const {<br class="">+  return str;<br class="">+}<br class="">+<br class="">+<br class="">+int main() {<br class="">+  StringUsed s1 ("test"), s2;<br class="">+  s2 = s1;<br class="">+  s2 = std::move(s1);<br class="">+  return 0;<br class="">+}<br class=""><br class=""><br class="">_______________________________________________<br class="">cfe-commits mailing list<br class="">cfe-commits@lists.llvm.org<br class="">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits<br class=""><br class=""><br class=""></blockquote></div></div></blockquote></div><br class=""></div></body></html>