[llvm-branch-commits] [cfe-branch] r278020 - Merging r277796, r277797, r277866, r277889 and r277900:

Hans Wennborg via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Aug 8 09:37:01 PDT 2016


Author: hans
Date: Mon Aug  8 11:37:00 2016
New Revision: 278020

URL: http://llvm.org/viewvc/llvm-project?rev=278020&view=rev
Log:
Merging r277796, r277797, r277866, r277889 and r277900:

------------------------------------------------------------------------
r277796 | rtrieu | 2016-08-04 19:39:30 -0700 (Thu, 04 Aug 2016) | 6 lines

Allow -1 to assign max value to unsigned bitfields.

Silence the -Wbitfield-constant-conversion warning for when -1 or other
negative values are assigned to unsigned bitfields, provided that the bitfield
is wider than the minimum number of bits needed to encode the negative value.

------------------------------------------------------------------------

------------------------------------------------------------------------
r277797 | rtrieu | 2016-08-04 20:16:36 -0700 (Thu, 04 Aug 2016) | 7 lines

Fix crash in template type diffing.

When the type being diffed is a type alias, and the orginal type is not a
templated type, then there will be no unsugared TemplateSpecializationType.
When this happens, exit early from the constructor.  Also add assertions to
the other iterator accessor to prevent the iterator from being used.

------------------------------------------------------------------------

------------------------------------------------------------------------
r277866 | rtrieu | 2016-08-05 14:02:34 -0700 (Fri, 05 Aug 2016) | 12 lines

Fix false positive in -Wunsequenced and templates.

For builtin logical operators, there is a well-defined ordering of argument
evaluation.  For overloaded operator of the same type, there is no argument
evaluation order, similar to other function calls.  When both are present,
uninstantiated templates with an operator&& is treated as an unresolved
function call.  Unresolved function calls are treated as normal function calls,
and may result in false positives when the builtin logical operator is used.
Have the unsequenced checker ignore dependent expressions to avoid this
false positive.  The check also happens in template instantiations to catch
when the overloaded operator is used.

------------------------------------------------------------------------

------------------------------------------------------------------------
r277889 | rtrieu | 2016-08-05 16:24:47 -0700 (Fri, 05 Aug 2016) | 9 lines

Fix two false positives in -Wreturn-stack-address

If the return type is a pointer and the function returns the reference to a
pointer, don't warn since only the value is returned, not the reference.

If a reference function parameter appears in the reference chain, don't warn
since binding happens at the caller scope, so addresses returned are not
to local stack.  This includes default arguments as well.

------------------------------------------------------------------------

------------------------------------------------------------------------
r277900 | rtrieu | 2016-08-05 18:44:06 -0700 (Fri, 05 Aug 2016) | 2 lines

Fix typos from r277797 and unused variable from r277889.

------------------------------------------------------------------------

Modified:
    cfe/branches/release_39/   (props changed)
    cfe/branches/release_39/lib/AST/ASTDiagnostic.cpp
    cfe/branches/release_39/lib/Sema/SemaChecking.cpp
    cfe/branches/release_39/test/Misc/diag-template-diffing.cpp
    cfe/branches/release_39/test/Sema/bitfield.c
    cfe/branches/release_39/test/Sema/constant-conversion.c
    cfe/branches/release_39/test/SemaCXX/return-stack-addr-2.cpp
    cfe/branches/release_39/test/SemaCXX/warn-unsequenced.cpp

Propchange: cfe/branches/release_39/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Aug  8 11:37:00 2016
@@ -1,4 +1,4 @@
 /cfe/branches/type-system-rewrite:134693-134817
-/cfe/trunk:275880,275967,276102,276350,276361,276473,276653,276716,276887,276891,276979,276983,277095,277138,277141,277221,277307,277743
+/cfe/trunk:275880,275967,276102,276350,276361,276473,276653,276716,276887,276891,276979,276983,277095,277138,277141,277221,277307,277743,277796-277797,277866,277889,277900
 /cfe/trunk/test:170344
 /cfe/trunk/test/SemaTemplate:126920

Modified: cfe/branches/release_39/lib/AST/ASTDiagnostic.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/lib/AST/ASTDiagnostic.cpp?rev=278020&r1=278019&r2=278020&view=diff
==============================================================================
--- cfe/branches/release_39/lib/AST/ASTDiagnostic.cpp (original)
+++ cfe/branches/release_39/lib/AST/ASTDiagnostic.cpp Mon Aug  8 11:37:00 2016
@@ -917,6 +917,8 @@ class TemplateDiff {
       /// template argument.
       InternalIterator(const TemplateSpecializationType *TST)
           : TST(TST), Index(0), CurrentTA(nullptr), EndTA(nullptr) {
+        if (!TST) return;
+
         if (isEnd()) return;
 
         // Set to first template argument.  If not a parameter pack, done.
@@ -937,11 +939,13 @@ class TemplateDiff {
 
       /// isEnd - Returns true if the iterator is one past the end.
       bool isEnd() const {
+        assert(TST && "InternalIterator is invalid with a null TST.");
         return Index >= TST->getNumArgs();
       }
 
       /// &operator++ - Increment the iterator to the next template argument.
       InternalIterator &operator++() {
+        assert(TST && "InternalIterator is invalid with a null TST.");
         if (isEnd()) {
           return *this;
         }
@@ -977,6 +981,7 @@ class TemplateDiff {
 
       /// operator* - Returns the appropriate TemplateArgument.
       reference operator*() const {
+        assert(TST && "InternalIterator is invalid with a null TST.");
         assert(!isEnd() && "Index exceeds number of arguments.");
         if (CurrentTA == EndTA)
           return TST->getArg(Index);
@@ -986,6 +991,7 @@ class TemplateDiff {
 
       /// operator-> - Allow access to the underlying TemplateArgument.
       pointer operator->() const {
+        assert(TST && "InternalIterator is invalid with a null TST.");
         return &operator*();
       }
     };

Modified: cfe/branches/release_39/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/lib/Sema/SemaChecking.cpp?rev=278020&r1=278019&r2=278020&view=diff
==============================================================================
--- cfe/branches/release_39/lib/Sema/SemaChecking.cpp (original)
+++ cfe/branches/release_39/lib/Sema/SemaChecking.cpp Mon Aug  8 11:37:00 2016
@@ -6523,6 +6523,12 @@ CheckReturnStackAddr(Sema &S, Expr *RetV
   if (!stackE)
     return; // Nothing suspicious was found.
 
+  // Parameters are initalized in the calling scope, so taking the address
+  // of a parameter reference doesn't need a warning.
+  for (auto *DRE : refVars)
+    if (isa<ParmVarDecl>(DRE->getDecl()))
+      return;
+
   SourceLocation diagLoc;
   SourceRange diagRange;
   if (refVars.empty()) {
@@ -6546,6 +6552,13 @@ CheckReturnStackAddr(Sema &S, Expr *RetV
   } else if (isa<AddrLabelExpr>(stackE)) { // address of label.
     S.Diag(diagLoc, diag::warn_ret_addr_label) << diagRange;
   } else { // local temporary.
+    // If there is an LValue->RValue conversion, then the value of the
+    // reference type is used, not the reference.
+    if (auto *ICE = dyn_cast<ImplicitCastExpr>(RetValExp)) {
+      if (ICE->getCastKind() == CK_LValueToRValue) {
+        return;
+      }
+    }
     S.Diag(diagLoc, diag::warn_ret_local_temp_addr_ref)
      << lhsType->isReferenceType() << diagRange;
   }
@@ -7776,6 +7789,12 @@ bool AnalyzeBitFieldAssignment(Sema &S,
   unsigned OriginalWidth = Value.getBitWidth();
   unsigned FieldWidth = Bitfield->getBitWidthValue(S.Context);
 
+  if (Value.isSigned() && Value.isNegative())
+    if (UnaryOperator *UO = dyn_cast<UnaryOperator>(OriginalInit))
+      if (UO->getOpcode() == UO_Minus)
+        if (isa<IntegerLiteral>(UO->getSubExpr()))
+          OriginalWidth = Value.getMinSignedBits();
+
   if (OriginalWidth <= FieldWidth)
     return false;
 
@@ -9372,7 +9391,8 @@ void Sema::CheckUnsequencedOperations(Ex
 void Sema::CheckCompletedExpr(Expr *E, SourceLocation CheckLoc,
                               bool IsConstexpr) {
   CheckImplicitConversions(E, CheckLoc);
-  CheckUnsequencedOperations(E);
+  if (!E->isInstantiationDependent())
+    CheckUnsequencedOperations(E);
   if (!IsConstexpr && !E->isValueDependent())
     CheckForIntOverflow(E);
 }

Modified: cfe/branches/release_39/test/Misc/diag-template-diffing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/test/Misc/diag-template-diffing.cpp?rev=278020&r1=278019&r2=278020&view=diff
==============================================================================
--- cfe/branches/release_39/test/Misc/diag-template-diffing.cpp (original)
+++ cfe/branches/release_39/test/Misc/diag-template-diffing.cpp Mon Aug  8 11:37:00 2016
@@ -1455,7 +1455,37 @@ void run() {
 }
 // CHECK-ELIDE-NOTREE: error: no matching function for call to 'D'
 // CHECK-ELIDE-NOTREE: note: candidate function [with x = TypeAlias::X::X1] not viable: no known conversion from 'VectorType<X::X2>' to 'const VectorType<(TypeAlias::X)0>' for 1st argument
+}
+
+namespace TypeAlias2 {
+template <typename T>
+class A {};
+
+template <typename T>
+using A_reg = A<T>;
+void take_reg(A_reg<int>);
+
+template <typename T>
+using A_ptr = A<T> *;
+void take_ptr(A_ptr<int>);
 
+template <typename T>
+using A_ref = const A<T> &;
+void take_ref(A_ref<int>);
+
+void run(A_reg<float> reg, A_ptr<float> ptr, A_ref<float> ref) {
+  take_reg(reg);
+// CHECK-ELIDE-NOTREE: error: no matching function for call to 'take_reg'
+// CHECK-ELIDE-NOTREE: note:     candidate function not viable: no known conversion from 'A_reg<float>' to 'A_reg<int>' for 1st argument
+
+  take_ptr(ptr);
+// CHECK-ELIDE-NOTREE: error: no matching function for call to 'take_ptr'
+// CHECK-ELIDE-NOTREE: note:     candidate function not viable: no known conversion from 'A_ptr<float>' to 'A_ptr<int>' for 1st argument
+
+  take_ref(ref);
+// CHECK-ELIDE-NOTREE: error: no matching function for call to 'take_ref'
+// CHECK-ELIDE-NOTREE: note: candidate function not viable: no known conversion from 'const A<float>' to 'const A<int>' for 1st argument
+}
 }
 
 // CHECK-ELIDE-NOTREE: {{[0-9]*}} errors generated.

Modified: cfe/branches/release_39/test/Sema/bitfield.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/test/Sema/bitfield.c?rev=278020&r1=278019&r2=278020&view=diff
==============================================================================
--- cfe/branches/release_39/test/Sema/bitfield.c (original)
+++ cfe/branches/release_39/test/Sema/bitfield.c Mon Aug  8 11:37:00 2016
@@ -64,7 +64,7 @@ typedef signed Signed;
 
 struct Test5 { unsigned n : 2; } t5;
 // Bitfield is unsigned
-struct Test5 sometest5 = {-1}; // expected-warning {{implicit truncation from 'int' to bitfield changes value from -1 to 3}}
+struct Test5 sometest5 = {-1};
 typedef __typeof__(+t5.n) Signed;  // ... but promotes to signed.
 
 typedef __typeof__(t5.n + 0) Signed; // Arithmetic promotes.

Modified: cfe/branches/release_39/test/Sema/constant-conversion.c
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/test/Sema/constant-conversion.c?rev=278020&r1=278019&r2=278020&view=diff
==============================================================================
--- cfe/branches/release_39/test/Sema/constant-conversion.c (original)
+++ cfe/branches/release_39/test/Sema/constant-conversion.c Mon Aug  8 11:37:00 2016
@@ -113,3 +113,15 @@ void test9() {
 
   char array_init[] = { 255, 127, 128, 129, 0 };
 }
+
+void test10() {
+  struct S {
+    unsigned a : 4;
+  } s;
+  s.a = -1;
+  s.a = 15;
+  s.a = -8;
+
+  s.a = -9;  // expected-warning{{implicit truncation from 'int' to bitfield changes value from -9 to 7}}
+  s.a = 16;  // expected-warning{{implicit truncation from 'int' to bitfield changes value from 16 to 0}}
+}

Modified: cfe/branches/release_39/test/SemaCXX/return-stack-addr-2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/test/SemaCXX/return-stack-addr-2.cpp?rev=278020&r1=278019&r2=278020&view=diff
==============================================================================
--- cfe/branches/release_39/test/SemaCXX/return-stack-addr-2.cpp (original)
+++ cfe/branches/release_39/test/SemaCXX/return-stack-addr-2.cpp Mon Aug  8 11:37:00 2016
@@ -1,5 +1,4 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify -std=c++11 %s
-// expected-no-diagnostics
 
 namespace PR26599 {
 template <typename>
@@ -20,3 +19,63 @@ void *&pointer() {
 }
 }
 
+namespace LocalTemporary {
+
+template <class T>
+class QMap {
+public:
+  T value(const T &t = T()) const {
+    return t;
+  }
+};
+
+struct A {};
+
+void test() {
+  QMap<A *> map;
+  map.value();
+}
+
+typedef int* ptr;
+ptr int1(const ptr &p = ptr()) {
+  return (p);
+}
+
+ptr int2(const ptr &p = nullptr) {
+  return p;
+}
+
+ptr int3() {
+  const ptr &p = ptr();
+  return p;
+}
+
+const int *int4(const int &x = 5) {
+  return &x;
+}
+
+const int *int5(const int &x) {
+  return &x;
+}
+
+const int *int6() {
+  const int &x = 11;  //expected-note{{binding reference variable 'x' here}}
+  return &x;  //expected-warning{{returning address of local temporary object}}
+}
+
+const int *int7(int x) {
+  const int &x2 = x;  // expected-note{{binding reference variable 'x2' here}}
+  return &x2;  //  expected-warning{{address of stack memory associated with local variable 'x' returned}}
+}
+
+const int *int8(const int &x = 5) {
+  const int &x2 = x;
+  return &x2;
+}
+
+const int *int9() {
+  const int &x = 5;  // expected-note{{binding reference variable 'x' here}}
+  const int &x2 = x;  // expected-note{{binding reference variable 'x2' here}}
+  return &x2;  // expected-warning{{returning address of local temporary object}}
+}
+}

Modified: cfe/branches/release_39/test/SemaCXX/warn-unsequenced.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/branches/release_39/test/SemaCXX/warn-unsequenced.cpp?rev=278020&r1=278019&r2=278020&view=diff
==============================================================================
--- cfe/branches/release_39/test/SemaCXX/warn-unsequenced.cpp (original)
+++ cfe/branches/release_39/test/SemaCXX/warn-unsequenced.cpp Mon Aug  8 11:37:00 2016
@@ -113,3 +113,58 @@ void test() {
   (__builtin_object_size(&(++a, a), 0) ? 1 : 0) + ++a; // ok
   (__builtin_expect(++a, 0) ? 1 : 0) + ++a; // expected-warning {{multiple unsequenced modifications}}
 }
+
+namespace templates {
+
+template <typename T>
+struct Bar {
+  T get() { return 0; }
+};
+
+template <typename X>
+struct Foo {
+  int Run();
+  Bar<int> bar;
+};
+
+enum E {e1, e2};
+bool operator&&(E, E);
+
+void foo(int, int);
+
+template <typename X>
+int Foo<X>::Run() {
+  char num = 0;
+
+  // Before instantiation, Clang may consider the builtin operator here as
+  // unresolved function calls, and treat the arguments as unordered when
+  // the builtin operator evaluatation is well-ordered.  Waiting until
+  // instantiation to check these expressions will prevent false positives.
+  if ((num = bar.get()) < 5 && num < 10) { }
+  if ((num = bar.get()) < 5 || num < 10) { }
+  if (static_cast<E>((num = bar.get()) < 5) || static_cast<E>(num < 10)) { }
+
+  if (static_cast<E>((num = bar.get()) < 5) && static_cast<E>(num < 10)) { }
+  // expected-warning at -1 {{unsequenced modification and access to 'num'}}
+
+  foo(num++, num++);
+  // expected-warning at -1 2{{multiple unsequenced modifications to 'num'}}
+  return 1;
+}
+
+int x = Foo<int>().Run();
+// expected-note at -1 {{in instantiation of member function 'templates::Foo<int>::Run'}}
+
+
+template <typename T>
+int Run2() {
+  T t = static_cast<T>(0);
+  return (t = static_cast<T>(1)) && t;
+  // expected-warning at -1 {{unsequenced modification and access to 't'}}
+}
+
+int y = Run2<bool>();
+int z = Run2<E>();
+// expected-note at -1{{in instantiation of function template specialization 'templates::Run2<templates::E>' requested here}}
+
+}




More information about the llvm-branch-commits mailing list