r284811 - Revert "DR583, DR1512: Implement a rewrite to C++'s 'composite pointer type' rules."

Renato Golin via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 21 01:03:50 PDT 2016


Author: rengolin
Date: Fri Oct 21 03:03:49 2016
New Revision: 284811

URL: http://llvm.org/viewvc/llvm-project?rev=284811&view=rev
Log:
Revert "DR583, DR1512: Implement a rewrite to C++'s 'composite pointer type' rules."

This reverts commit r284800, as it failed all ARM/AArch64 bots.

Removed:
    cfe/trunk/test/CXX/over/over.built/p15.cpp
    cfe/trunk/test/CXX/over/over.built/p16.cpp
    cfe/trunk/test/SemaCXX/libstdcxx_libcxx_less_hack.cpp
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp
    cfe/trunk/test/CXX/drs/dr15xx.cpp
    cfe/trunk/test/CXX/drs/dr5xx.cpp
    cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
    cfe/trunk/test/Misc/warning-flags.c
    cfe/trunk/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp
    cfe/trunk/test/OpenMP/distribute_simd_aligned_messages.cpp
    cfe/trunk/test/OpenMP/for_simd_aligned_messages.cpp
    cfe/trunk/test/OpenMP/parallel_for_simd_aligned_messages.cpp
    cfe/trunk/test/OpenMP/simd_aligned_messages.cpp
    cfe/trunk/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp
    cfe/trunk/test/OpenMP/target_simd_aligned_messages.cpp
    cfe/trunk/test/OpenMP/taskloop_simd_aligned_messages.cpp
    cfe/trunk/test/SemaCXX/compare.cpp
    cfe/trunk/test/SemaCXX/composite-pointer-type.cpp
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
    cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp
    cfe/trunk/test/SemaCXX/nullptr.cpp
    cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
    cfe/trunk/test/SemaCXX/warn-memsize-comparison.cpp
    cfe/trunk/test/SemaObjCXX/null_objc_pointer.mm
    cfe/trunk/www/cxx_dr_status.html

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Oct 21 03:03:49 2016
@@ -5536,8 +5536,6 @@ def ext_typecheck_ordered_comparison_of_
   "ordered comparison between pointer and integer (%0 and %1)">;
 def ext_typecheck_ordered_comparison_of_pointer_and_zero : Extension<
   "ordered comparison between pointer and zero (%0 and %1) is an extension">;
-def err_typecheck_ordered_comparison_of_pointer_and_zero : Error<
-  "ordered comparison between pointer and zero (%0 and %1)">;
 def ext_typecheck_ordered_comparison_of_function_pointers : ExtWarn<
   "ordered comparison of function pointers (%0 and %1)">;
 def ext_typecheck_comparison_of_fptr_to_void : Extension<
@@ -5558,6 +5556,9 @@ def err_cond_voidptr_arc : Error <
   "in ARC mode">;
 def err_typecheck_comparison_of_distinct_pointers : Error<
   "comparison of distinct pointer types%diff{ ($ and $)|}0,1">;
+def ext_typecheck_comparison_of_distinct_pointers_nonstandard : ExtWarn<
+  "comparison of distinct pointer types (%0 and %1) uses non-standard "
+  "composite pointer type %2">, InGroup<CompareDistinctPointerType>;
 def err_typecheck_op_on_nonoverlapping_address_space_pointers : Error<
   "%select{comparison between %diff{ ($ and $)|}0,1"
   "|arithmetic operation with operands of type %diff{ ($ and $)|}0,1"
@@ -6836,6 +6837,9 @@ def err_typecheck_expect_scalar_operand
   "operand of type %0 where arithmetic or pointer type is required">;
 def err_typecheck_cond_incompatible_operands : Error<
   "incompatible operand types%diff{ ($ and $)|}0,1">;
+def ext_typecheck_cond_incompatible_operands_nonstandard : ExtWarn<
+  "incompatible operand types%diff{ ($ and $)|}0,1 use non-standard composite "
+  "pointer type %2">;
 def err_cast_selector_expr : Error<
   "cannot type cast @selector expression">;
 def ext_typecheck_cond_incompatible_pointers : ExtWarn<

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Oct 21 03:03:49 2016
@@ -8954,13 +8954,15 @@ public:
     ExprResult &cond, ExprResult &lhs, ExprResult &rhs,
     ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc);
   QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2,
+                                    bool *NonStandardCompositeType = nullptr,
                                     bool ConvertArgs = true);
   QualType FindCompositePointerType(SourceLocation Loc,
                                     ExprResult &E1, ExprResult &E2,
+                                    bool *NonStandardCompositeType = nullptr,
                                     bool ConvertArgs = true) {
     Expr *E1Tmp = E1.get(), *E2Tmp = E2.get();
-    QualType Composite =
-        FindCompositePointerType(Loc, E1Tmp, E2Tmp, ConvertArgs);
+    QualType Composite = FindCompositePointerType(
+        Loc, E1Tmp, E2Tmp, NonStandardCompositeType, ConvertArgs);
     E1 = E1Tmp;
     E2 = E2Tmp;
     return Composite;

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Oct 21 03:03:49 2016
@@ -8929,21 +8929,35 @@ static bool convertPointersToCompositeTy
   // C++ [expr.eq]p1 uses the same notion for (in)equality
   // comparisons of pointers.
 
+  // C++ [expr.eq]p2:
+  //   In addition, pointers to members can be compared, or a pointer to
+  //   member and a null pointer constant. Pointer to member conversions
+  //   (4.11) and qualification conversions (4.4) are performed to bring
+  //   them to a common type. If one operand is a null pointer constant,
+  //   the common type is the type of the other operand. Otherwise, the
+  //   common type is a pointer to member type similar (4.4) to the type
+  //   of one of the operands, with a cv-qualification signature (4.4)
+  //   that is the union of the cv-qualification signatures of the operand
+  //   types.
+
   QualType LHSType = LHS.get()->getType();
   QualType RHSType = RHS.get()->getType();
-  assert(LHSType->isPointerType() || RHSType->isPointerType() ||
-         LHSType->isMemberPointerType() || RHSType->isMemberPointerType());
+  assert((LHSType->isPointerType() && RHSType->isPointerType()) ||
+         (LHSType->isMemberPointerType() && RHSType->isMemberPointerType()));
 
-  QualType T = S.FindCompositePointerType(Loc, LHS, RHS);
+  bool NonStandardCompositeType = false;
+  bool *BoolPtr = S.isSFINAEContext() ? nullptr : &NonStandardCompositeType;
+  QualType T = S.FindCompositePointerType(Loc, LHS, RHS, BoolPtr);
   if (T.isNull()) {
-    if ((LHSType->isPointerType() || LHSType->isMemberPointerType()) &&
-        (RHSType->isPointerType() || RHSType->isMemberPointerType()))
-      diagnoseDistinctPointerComparison(S, Loc, LHS, RHS, /*isError*/true);
-    else
-      S.InvalidOperands(Loc, LHS, RHS);
+    diagnoseDistinctPointerComparison(S, Loc, LHS, RHS, /*isError*/true);
     return true;
   }
 
+  if (NonStandardCompositeType)
+    S.Diag(Loc, diag::ext_typecheck_comparison_of_distinct_pointers_nonstandard)
+      << LHSType << RHSType << T << LHS.get()->getSourceRange()
+      << RHS.get()->getSourceRange();
+
   LHS = S.ImpCastExprToType(LHS.get(), T, CK_BitCast);
   RHS = S.ImpCastExprToType(RHS.get(), T, CK_BitCast);
   return false;
@@ -9300,53 +9314,41 @@ QualType Sema::CheckCompareOperands(Expr
                                    LHS.get()->getSourceRange());
   }
 
-  if ((LHSType->isIntegerType() && !LHSIsNull) ||
-      (RHSType->isIntegerType() && !RHSIsNull)) {
-    // Skip normal pointer conversion checks in this case; we have better
-    // diagnostics for this below.
-  } else if (getLangOpts().CPlusPlus) {
-    // Equality comparison of a function pointer to a void pointer is invalid,
-    // but we allow it as an extension.
-    // FIXME: If we really want to allow this, should it be part of composite
-    // pointer type computation so it works in conditionals too?
-    if (!IsRelational &&
-        ((LHSType->isFunctionPointerType() && RHSType->isVoidPointerType()) ||
-         (RHSType->isFunctionPointerType() && LHSType->isVoidPointerType()))) {
-      // This is a gcc extension compatibility comparison.
-      // In a SFINAE context, we treat this as a hard error to maintain
-      // conformance with the C++ standard.
-      diagnoseFunctionPointerToVoidComparison(
-          *this, Loc, LHS, RHS, /*isError*/ (bool)isSFINAEContext());
-      
-      if (isSFINAEContext())
-        return QualType();
-      
-      RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
-      return ResultTy;
-    }
+  // All of the following pointer-related warnings are GCC extensions, except
+  // when handling null pointer constants. 
+  if (LHSType->isPointerType() && RHSType->isPointerType()) { // C99 6.5.8p2
+    QualType LCanPointeeTy =
+      LHSType->castAs<PointerType>()->getPointeeType().getCanonicalType();
+    QualType RCanPointeeTy =
+      RHSType->castAs<PointerType>()->getPointeeType().getCanonicalType();
+
+    if (getLangOpts().CPlusPlus) {
+      if (LCanPointeeTy == RCanPointeeTy)
+        return ResultTy;
+      if (!IsRelational &&
+          (LCanPointeeTy->isVoidType() || RCanPointeeTy->isVoidType())) {
+        // Valid unless comparison between non-null pointer and function pointer
+        // This is a gcc extension compatibility comparison.
+        // In a SFINAE context, we treat this as a hard error to maintain
+        // conformance with the C++ standard.
+        if ((LCanPointeeTy->isFunctionType() || RCanPointeeTy->isFunctionType())
+            && !LHSIsNull && !RHSIsNull) {
+          diagnoseFunctionPointerToVoidComparison(
+              *this, Loc, LHS, RHS, /*isError*/ (bool)isSFINAEContext());
+          
+          if (isSFINAEContext())
+            return QualType();
+          
+          RHS = ImpCastExprToType(RHS.get(), LHSType, CK_BitCast);
+          return ResultTy;
+        }
+      }
 
-    // C++ [expr.eq]p2:
-    //   If at least one operand is a pointer [...] bring them to their
-    //   composite pointer type.
-    // C++ [expr.rel]p2:
-    //   If both operands are pointers, [...] bring them to their composite
-    //   pointer type.
-    if ((int)LHSType->isPointerType() + (int)RHSType->isPointerType() >=
-        (IsRelational ? 2 : 1)) {
       if (convertPointersToCompositeType(*this, Loc, LHS, RHS))
         return QualType();
       else
         return ResultTy;
     }
-  } else if (LHSType->isPointerType() &&
-             RHSType->isPointerType()) { // C99 6.5.8p2
-    // All of the following pointer-related warnings are GCC extensions, except
-    // when handling null pointer constants.
-    QualType LCanPointeeTy =
-      LHSType->castAs<PointerType>()->getPointeeType().getCanonicalType();
-    QualType RCanPointeeTy =
-      RHSType->castAs<PointerType>()->getPointeeType().getCanonicalType();
-
     // C99 6.5.9p2 and C99 6.5.8p2
     if (Context.typesAreCompatible(LCanPointeeTy.getUnqualifiedType(),
                                    RCanPointeeTy.getUnqualifiedType())) {
@@ -9391,63 +9393,36 @@ QualType Sema::CheckCompareOperands(Expr
   }
 
   if (getLangOpts().CPlusPlus) {
-    // C++ [expr.eq]p4:
-    //   Two operands of type std::nullptr_t or one operand of type
-    //   std::nullptr_t and the other a null pointer constant compare equal.
-    if (!IsRelational && LHSIsNull && RHSIsNull) {
-      if (LHSType->isNullPtrType()) {
-        RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
-        return ResultTy;
-      }
-      if (RHSType->isNullPtrType()) {
-        LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
-        return ResultTy;
-      }
-    }
-
-    // Comparison of Objective-C pointers and block pointers against nullptr_t.
-    // These aren't covered by the composite pointer type rules.
-    if (!IsRelational && RHSType->isNullPtrType() &&
-        (LHSType->isObjCObjectPointerType() || LHSType->isBlockPointerType())) {
-      RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
+    // Comparison of nullptr_t with itself.
+    if (LHSType->isNullPtrType() && RHSType->isNullPtrType())
       return ResultTy;
-    }
-    if (!IsRelational && LHSType->isNullPtrType() &&
-        (RHSType->isObjCObjectPointerType() || RHSType->isBlockPointerType())) {
-      LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
+    
+    // Comparison of pointers with null pointer constants and equality
+    // comparisons of member pointers to null pointer constants.
+    if (RHSIsNull &&
+        ((LHSType->isAnyPointerType() || LHSType->isNullPtrType()) ||
+         (!IsRelational && 
+          (LHSType->isMemberPointerType() || LHSType->isBlockPointerType())))) {
+      RHS = ImpCastExprToType(RHS.get(), LHSType, 
+                        LHSType->isMemberPointerType()
+                          ? CK_NullToMemberPointer
+                          : CK_NullToPointer);
       return ResultTy;
     }
-
-    if (IsRelational &&
-        ((LHSType->isNullPtrType() && RHSType->isPointerType()) ||
-         (RHSType->isNullPtrType() && LHSType->isPointerType()))) {
-      // HACK: Relational comparison of nullptr_t against a pointer type is
-      // invalid per DR583, but we allow it within std::less<> and friends,
-      // since otherwise common uses of it break.
-      // FIXME: Consider removing this hack once LWG fixes std::less<> and
-      // friends to have std::nullptr_t overload candidates.
-      DeclContext *DC = CurContext;
-      if (isa<FunctionDecl>(DC))
-        DC = DC->getParent();
-      if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
-        if (CTSD->isInStdNamespace() &&
-            llvm::StringSwitch<bool>(CTSD->getName())
-                .Cases("less", "less_equal", "greater", "greater_equal", true)
-                .Default(false)) {
-          if (RHSType->isNullPtrType())
-            RHS = ImpCastExprToType(RHS.get(), LHSType, CK_NullToPointer);
-          else
-            LHS = ImpCastExprToType(LHS.get(), RHSType, CK_NullToPointer);
-          return ResultTy;
-        }
-      }
+    if (LHSIsNull &&
+        ((RHSType->isAnyPointerType() || RHSType->isNullPtrType()) ||
+         (!IsRelational && 
+          (RHSType->isMemberPointerType() || RHSType->isBlockPointerType())))) {
+      LHS = ImpCastExprToType(LHS.get(), RHSType, 
+                        RHSType->isMemberPointerType()
+                          ? CK_NullToMemberPointer
+                          : CK_NullToPointer);
+      return ResultTy;
     }
 
-    // C++ [expr.eq]p2:
-    //   If at least one operand is a pointer to member, [...] bring them to
-    //   their composite pointer type.
+    // Comparison of member pointers.
     if (!IsRelational &&
-        (LHSType->isMemberPointerType() || RHSType->isMemberPointerType())) {
+        LHSType->isMemberPointerType() && RHSType->isMemberPointerType()) {
       if (convertPointersToCompositeType(*this, Loc, LHS, RHS))
         return QualType();
       else
@@ -9556,19 +9531,15 @@ QualType Sema::CheckCompareOperands(Expr
       // Under a debugger, allow the comparison of pointers to integers,
       // since users tend to want to compare addresses.
     } else if ((LHSIsNull && LHSType->isIntegerType()) ||
-               (RHSIsNull && RHSType->isIntegerType())) {
-      if (IsRelational) {
-        isError = getLangOpts().CPlusPlus;
-        DiagID =
-          isError ? diag::err_typecheck_ordered_comparison_of_pointer_and_zero
-                  : diag::ext_typecheck_ordered_comparison_of_pointer_and_zero;
-      }
-    } else if (getLangOpts().CPlusPlus) {
+        (RHSIsNull && RHSType->isIntegerType())) {
+      if (IsRelational && !getLangOpts().CPlusPlus)
+        DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_and_zero;
+    } else if (IsRelational && !getLangOpts().CPlusPlus)
+      DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_integer;
+    else if (getLangOpts().CPlusPlus) {
       DiagID = diag::err_typecheck_comparison_of_pointer_integer;
       isError = true;
-    } else if (IsRelational)
-      DiagID = diag::ext_typecheck_ordered_comparison_of_pointer_integer;
-    else
+    } else
       DiagID = diag::ext_typecheck_comparison_of_pointer_integer;
 
     if (DiagID) {

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Oct 21 03:03:49 2016
@@ -5399,7 +5399,7 @@ QualType Sema::CXXCheckConditionalOperan
     // exception specifications, if any.
     if (LTy->isFunctionPointerType() || LTy->isMemberFunctionPointerType()) {
       Qualifiers Qs = LTy.getQualifiers();
-      LTy = FindCompositePointerType(QuestionLoc, LHS, RHS,
+      LTy = FindCompositePointerType(QuestionLoc, LHS, RHS, nullptr,
                                      /*ConvertArgs*/false);
       LTy = Context.getQualifiedType(LTy, Qs);
 
@@ -5511,9 +5511,19 @@ QualType Sema::CXXCheckConditionalOperan
   //      performed to bring them to a common type, whose cv-qualification
   //      shall match the cv-qualification of either the second or the third
   //      operand. The result is of the common type.
-  QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS);
-  if (!Composite.isNull())
+  bool NonStandardCompositeType = false;
+  QualType Composite = FindCompositePointerType(QuestionLoc, LHS, RHS,
+                                 isSFINAEContext() ? nullptr
+                                                   : &NonStandardCompositeType);
+  if (!Composite.isNull()) {
+    if (NonStandardCompositeType)
+      Diag(QuestionLoc,
+           diag::ext_typecheck_cond_incompatible_operands_nonstandard)
+        << LTy << RTy << Composite
+        << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
+
     return Composite;
+  }
 
   // Similarly, attempt to find composite type of two objective-c pointers.
   Composite = FindCompositeObjCPointerType(LHS, RHS, QuestionLoc);
@@ -5612,10 +5622,19 @@ mergeExceptionSpecs(Sema &S, FunctionPro
 /// \param Loc The location of the operator requiring these two expressions to
 /// be converted to the composite pointer type.
 ///
+/// If \p NonStandardCompositeType is non-NULL, then we are permitted to find
+/// a non-standard (but still sane) composite type to which both expressions
+/// can be converted. When such a type is chosen, \c *NonStandardCompositeType
+/// will be set true.
+///
 /// \param ConvertArgs If \c false, do not convert E1 and E2 to the target type.
 QualType Sema::FindCompositePointerType(SourceLocation Loc,
                                         Expr *&E1, Expr *&E2,
+                                        bool *NonStandardCompositeType,
                                         bool ConvertArgs) {
+  if (NonStandardCompositeType)
+    *NonStandardCompositeType = false;
+
   assert(getLangOpts().CPlusPlus && "This function assumes C++");
 
   // C++1z [expr]p14:
@@ -5708,7 +5727,8 @@ QualType Sema::FindCompositePointerType(
 
       // If we're allowed to create a non-standard composite type, keep track
       // of where we need to fill in additional 'const' qualifiers.
-      if (Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
+      if (NonStandardCompositeType &&
+          Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
         NeedConstBefore = QualifierUnion.size();
 
       QualifierUnion.push_back(
@@ -5725,7 +5745,8 @@ QualType Sema::FindCompositePointerType(
 
       // If we're allowed to create a non-standard composite type, keep track
       // of where we need to fill in additional 'const' qualifiers.
-      if (Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
+      if (NonStandardCompositeType &&
+          Composite1.getCVRQualifiers() != Composite2.getCVRQualifiers())
         NeedConstBefore = QualifierUnion.size();
 
       QualifierUnion.push_back(
@@ -5776,13 +5797,16 @@ QualType Sema::FindCompositePointerType(
     }
   }
 
-  if (NeedConstBefore) {
+  if (NeedConstBefore && NonStandardCompositeType) {
     // Extension: Add 'const' to qualifiers that come before the first qualifier
     // mismatch, so that our (non-standard!) composite type meets the
     // requirements of C++ [conv.qual]p4 bullet 3.
-    for (unsigned I = 0; I != NeedConstBefore; ++I)
-      if ((QualifierUnion[I] & Qualifiers::Const) == 0)
+    for (unsigned I = 0; I != NeedConstBefore; ++I) {
+      if ((QualifierUnion[I] & Qualifiers::Const) == 0) {
         QualifierUnion[I] = QualifierUnion[I] | Qualifiers::Const;
+        *NonStandardCompositeType = true;
+      }
+    }
   }
 
   // Rewrap the composites as pointers or member pointers with the union CVRs.

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Fri Oct 21 03:03:49 2016
@@ -7624,12 +7624,12 @@ public:
   }
 
   // C++ [over.match.oper]p16:
-  //   For every pointer to member type T or type std::nullptr_t, there
-  //   exist candidate operator functions of the form
+  //   For every pointer to member type T, there exist candidate operator
+  //   functions of the form
   //
   //        bool operator==(T,T);
   //        bool operator!=(T,T);
-  void addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads() {
+  void addEqualEqualOrNotEqualMemberPointerOverloads() {
     /// Set of (canonical) types that we've already handled.
     llvm::SmallPtrSet<QualType, 8> AddedTypes;
 
@@ -7646,22 +7646,13 @@ public:
         QualType ParamTypes[2] = { *MemPtr, *MemPtr };
         S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet);
       }
-
-      if (CandidateTypes[ArgIdx].hasNullPtrType()) {
-        CanQualType NullPtrTy = S.Context.getCanonicalType(S.Context.NullPtrTy);
-        if (AddedTypes.insert(NullPtrTy).second) {
-          QualType ParamTypes[2] = { NullPtrTy, NullPtrTy };
-          S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args,
-                                CandidateSet);
-        }
-      }
     }
   }
 
   // C++ [over.built]p15:
   //
-  //   For every T, where T is an enumeration type or a pointer type,
-  //   there exist candidate operator functions of the form
+  //   For every T, where T is an enumeration type, a pointer type, or 
+  //   std::nullptr_t, there exist candidate operator functions of the form
   //
   //        bool       operator<(T, T);
   //        bool       operator>(T, T);
@@ -7746,6 +7737,17 @@ public:
         QualType ParamTypes[2] = { *Enum, *Enum };
         S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args, CandidateSet);
       }
+      
+      if (CandidateTypes[ArgIdx].hasNullPtrType()) {
+        CanQualType NullPtrTy = S.Context.getCanonicalType(S.Context.NullPtrTy);
+        if (AddedTypes.insert(NullPtrTy).second &&
+            !UserDefinedBinaryOperators.count(std::make_pair(NullPtrTy,
+                                                             NullPtrTy))) {
+          QualType ParamTypes[2] = { NullPtrTy, NullPtrTy };
+          S.AddBuiltinCandidate(S.Context.BoolTy, ParamTypes, Args,
+                                CandidateSet);
+        }
+      }
     }
   }
 
@@ -8441,7 +8443,7 @@ void Sema::AddBuiltinOperatorCandidates(
 
   case OO_EqualEqual:
   case OO_ExclaimEqual:
-    OpBuilder.addEqualEqualOrNotEqualMemberPointerOrNullptrOverloads();
+    OpBuilder.addEqualEqualOrNotEqualMemberPointerOverloads();
     // Fall through.
 
   case OO_Less:

Modified: cfe/trunk/test/CXX/drs/dr15xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr15xx.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr15xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr15xx.cpp Fri Oct 21 03:03:49 2016
@@ -3,137 +3,9 @@
 // RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 // RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
 
-namespace dr1512 { // dr1512: 4.0
-  void f(char *p) {
-    if (p > 0) {} // expected-error {{ordered comparison between pointer and zero}}
-#if __cplusplus >= 201103L
-    if (p > nullptr) {} // expected-error {{invalid operands}}
+#if __cplusplus < 201103L
+// expected-no-diagnostics
 #endif
-  }
-  bool g(int **x, const int **y) {
-    return x < y;
-  }
-
-  template<typename T> T val();
-
-  template<typename A, typename B, typename C> void composite_pointer_type_is_base() {
-    typedef __typeof(true ? val<A>() : val<B>()) type;
-    typedef C type;
-
-    typedef __typeof(val<A>() == val<B>()) cmp;
-    typedef __typeof(val<A>() != val<B>()) cmp;
-    typedef bool cmp;
-  }
-
-  template<typename A, typename B, typename C> void composite_pointer_type_is_ord() {
-    composite_pointer_type_is_base<A, B, C>();
-
-    typedef __typeof(val<A>() < val<B>()) cmp;
-    typedef __typeof(val<A>() <= val<B>()) cmp;
-    typedef __typeof(val<A>() > val<B>()) cmp;
-    typedef __typeof(val<A>() >= val<B>()) cmp;
-    typedef bool cmp;
-  }
-
-  template <typename A, typename B, typename C>
-  void composite_pointer_type_is_unord(int = 0) {
-    composite_pointer_type_is_base<A, B, C>();
-  }
-  template <typename A, typename B, typename C>
-  void composite_pointer_type_is_unord(__typeof(val<A>() < val<B>()) * = 0);
-  template <typename A, typename B, typename C>
-  void composite_pointer_type_is_unord(__typeof(val<A>() <= val<B>()) * = 0);
-  template <typename A, typename B, typename C>
-  void composite_pointer_type_is_unord(__typeof(val<A>() > val<B>()) * = 0);
-  template <typename A, typename B, typename C>
-  void composite_pointer_type_is_unord(__typeof(val<A>() >= val<B>()) * = 0);
-
-  // A call to this is ambiguous if a composite pointer type exists.
-  template<typename A, typename B>
-  void no_composite_pointer_type(__typeof((true ? val<A>() : val<B>()), void()) * = 0);
-  template<typename A, typename B> void no_composite_pointer_type(int = 0);
-
-  struct A {};
-  struct B : A {};
-  struct C {};
-
-  void test() {
-#if __cplusplus >= 201103L
-    using nullptr_t = decltype(nullptr);
-    composite_pointer_type_is_unord<nullptr_t, nullptr_t, nullptr_t>();
-    no_composite_pointer_type<nullptr_t, int>();
-
-    composite_pointer_type_is_unord<nullptr_t, const char**, const char**>();
-    composite_pointer_type_is_unord<const char**, nullptr_t, const char**>();
-#endif
-
-    composite_pointer_type_is_ord<const int *, volatile void *, const volatile void*>();
-    composite_pointer_type_is_ord<const void *, volatile int *, const volatile void*>();
-
-    composite_pointer_type_is_ord<const A*, volatile B*, const volatile A*>();
-    composite_pointer_type_is_ord<const B*, volatile A*, const volatile A*>();
-
-    composite_pointer_type_is_unord<const int *A::*, volatile int *B::*, const volatile int *const B::*>();
-    composite_pointer_type_is_unord<const int *B::*, volatile int *A::*, const volatile int *const B::*>();
-    no_composite_pointer_type<int (A::*)(), int (C::*)()>();
-    no_composite_pointer_type<const int (A::*)(), volatile int (C::*)()>();
-
-#if __cplusplus > 201402
-    composite_pointer_type_is_ord<int (*)() noexcept, int (*)(), int (*)()>();
-    composite_pointer_type_is_ord<int (*)(), int (*)() noexcept, int (*)()>();
-    composite_pointer_type_is_unord<int (A::*)() noexcept, int (A::*)(), int (A::*)()>();
-    composite_pointer_type_is_unord<int (A::*)(), int (A::*)() noexcept, int (A::*)()>();
-    // FIXME: This looks like a standard defect; these should probably all have type 'int (B::*)()'.
-    composite_pointer_type_is_unord<int (B::*)(), int (A::*)() noexcept, int (B::*)()>();
-    composite_pointer_type_is_unord<int (A::*)() noexcept, int (B::*)(), int (B::*)()>();
-    composite_pointer_type_is_unord<int (B::*)() noexcept, int (A::*)(), int (B::*)()>();
-    composite_pointer_type_is_unord<int (A::*)(), int (B::*)() noexcept, int (B::*)()>();
-
-    // FIXME: It would be reasonable to permit these, with a common type of 'int (*const *)()'.
-    no_composite_pointer_type<int (**)() noexcept, int (**)()>();
-    no_composite_pointer_type<int (**)(), int (**)() noexcept>();
-
-    // FIXME: It would be reasonable to permit these, with a common type of 'int (A::*)()'.
-    no_composite_pointer_type<int (A::*)() const, int (A::*)()>();
-    no_composite_pointer_type<int (A::*)(), int (A::*)() const>();
-
-    // FIXME: It would be reasonable to permit these, with a common type of
-    // 'int (A::*)() &' and 'int (A::*)() &&', respectively.
-    no_composite_pointer_type<int (A::*)() &, int (A::*)()>();
-    no_composite_pointer_type<int (A::*)(), int (A::*)() &>();
-    no_composite_pointer_type<int (A::*)() &&, int (A::*)()>();
-    no_composite_pointer_type<int (A::*)(), int (A::*)() &&>();
-
-    no_composite_pointer_type<int (A::*)() &&, int (A::*)() &>();
-    no_composite_pointer_type<int (A::*)() &, int (A::*)() &&>();
-
-    no_composite_pointer_type<int (C::*)(), int (A::*)() noexcept>();
-    no_composite_pointer_type<int (A::*)() noexcept, int (C::*)()>();
-#endif
-  }
-
-  template<typename T> struct Wrap { operator T(); };
-  void test_overload() {
-#if __cplusplus >= 201103L
-    using nullptr_t = decltype(nullptr);
-    void(Wrap<nullptr_t>() == Wrap<nullptr_t>());
-    void(Wrap<nullptr_t>() != Wrap<nullptr_t>());
-    void(Wrap<nullptr_t>() < Wrap<nullptr_t>()); // expected-error {{invalid operands}}
-    void(Wrap<nullptr_t>() > Wrap<nullptr_t>()); // expected-error {{invalid operands}}
-    void(Wrap<nullptr_t>() <= Wrap<nullptr_t>()); // expected-error {{invalid operands}}
-    void(Wrap<nullptr_t>() >= Wrap<nullptr_t>()); // expected-error {{invalid operands}}
-
-    // The wording change fails to actually disallow this. This is valid
-    // via the builtin operator<(int*, int*) etc.
-    void(Wrap<nullptr_t>() == Wrap<int*>());
-    void(Wrap<nullptr_t>() != Wrap<int*>());
-    void(Wrap<nullptr_t>() < Wrap<int*>());
-    void(Wrap<nullptr_t>() > Wrap<int*>());
-    void(Wrap<nullptr_t>() <= Wrap<int*>());
-    void(Wrap<nullptr_t>() >= Wrap<int*>());
-#endif
-  }
-}
 
 namespace dr1550 { // dr1550: yes
   int f(bool b, int n) {

Modified: cfe/trunk/test/CXX/drs/dr5xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr5xx.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr5xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr5xx.cpp Fri Oct 21 03:03:49 2016
@@ -863,13 +863,14 @@ namespace dr580 { // dr580: partial
 
 // dr582: na
 
-namespace dr583 { // dr583: 4.0
+namespace dr583 { // dr583: no
   // see n3624
   int *p;
-  bool b1 = p < 0; // expected-error {{ordered comparison between pointer and zero}}
-  bool b2 = p > 0; // expected-error {{ordered comparison between pointer and zero}}
-  bool b3 = p <= 0; // expected-error {{ordered comparison between pointer and zero}}
-  bool b4 = p >= 0; // expected-error {{ordered comparison between pointer and zero}}
+  // FIXME: These are all ill-formed.
+  bool b1 = p < 0;
+  bool b2 = p > 0;
+  bool b3 = p <= 0;
+  bool b4 = p >= 0;
 }
 
 // dr584: na

Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Fri Oct 21 03:03:49 2016
@@ -461,14 +461,14 @@ namespace UnspecifiedRelations {
   constexpr bool u2 = p > q; // expected-error {{constant expression}}
   constexpr bool u3 = p <= q; // expected-error {{constant expression}}
   constexpr bool u4 = p >= q; // expected-error {{constant expression}}
-  constexpr bool u5 = p < (int*)0; // expected-error {{constant expression}}
-  constexpr bool u6 = p <= (int*)0; // expected-error {{constant expression}}
-  constexpr bool u7 = p > (int*)0; // expected-error {{constant expression}}
-  constexpr bool u8 = p >= (int*)0; // expected-error {{constant expression}}
-  constexpr bool u9 = (int*)0 < q; // expected-error {{constant expression}}
-  constexpr bool u10 = (int*)0 <= q; // expected-error {{constant expression}}
-  constexpr bool u11 = (int*)0 > q; // expected-error {{constant expression}}
-  constexpr bool u12 = (int*)0 >= q; // expected-error {{constant expression}}
+  constexpr bool u5 = p < 0; // expected-error {{constant expression}}
+  constexpr bool u6 = p <= 0; // expected-error {{constant expression}}
+  constexpr bool u7 = p > 0; // expected-error {{constant expression}}
+  constexpr bool u8 = p >= 0; // expected-error {{constant expression}}
+  constexpr bool u9 = 0 < q; // expected-error {{constant expression}}
+  constexpr bool u10 = 0 <= q; // expected-error {{constant expression}}
+  constexpr bool u11 = 0 > q; // expected-error {{constant expression}}
+  constexpr bool u12 = 0 >= q; // expected-error {{constant expression}}
   void f(), g();
 
   constexpr void (*pf)() = &f, (*pg)() = &g;
@@ -522,7 +522,7 @@ namespace UnspecifiedRelations {
   constexpr void *null = 0;
   constexpr void *pv = (void*)&s.a;
   constexpr void *qv = (void*)&s.b;
-  constexpr bool v1 = null < (int*)0;
+  constexpr bool v1 = null < 0;
   constexpr bool v2 = null < pv; // expected-error {{constant expression}}
   constexpr bool v3 = null == pv; // ok
   constexpr bool v4 = qv == pv; // ok

Removed: cfe/trunk/test/CXX/over/over.built/p15.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/over/over.built/p15.cpp?rev=284810&view=auto
==============================================================================
--- cfe/trunk/test/CXX/over/over.built/p15.cpp (original)
+++ cfe/trunk/test/CXX/over/over.built/p15.cpp (removed)
@@ -1,83 +0,0 @@
-// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
-
-struct A { operator decltype(nullptr)(); };
-struct B { operator const int *(); };
-void f(A a, B b, volatile int *pi) {
-  (void)(a == a);
-  (void)(a != a);
-  (void)(a < a); // expected-error {{invalid operands}}
-  (void)(a > a); // expected-error {{invalid operands}}
-  (void)(a <= a); // expected-error {{invalid operands}}
-  (void)(a >= a); // expected-error {{invalid operands}}
-
-  (void)(a == b);
-  (void)(a != b);
-  // FIXME: These cases were intended to be made ill-formed by N3624, but it
-  // fails to actually achieve this goal.
-  (void)(a < b);
-  (void)(a > b);
-  (void)(a <= b);
-  (void)(a >= b);
-
-  (void)(b == a);
-  (void)(b != a);
-  // FIXME: These cases were intended to be made ill-formed by N3624, but it
-  // fails to actually achieve this goal.
-  (void)(b < a);
-  (void)(b > a);
-  (void)(b <= a);
-  (void)(b >= a);
-
-  (void)(a == pi);
-  (void)(a != pi);
-  // FIXME: These cases were intended to be made ill-formed by N3624, but it
-  // fails to actually achieve this goal.
-  (void)(a < pi);
-  (void)(a > pi);
-  (void)(a <= pi);
-  (void)(a >= pi);
-
-  (void)(pi == a);
-  (void)(pi != a);
-  // FIXME: These cases were intended to be made ill-formed by N3624, but it
-  // fails to actually achieve this goal.
-  (void)(pi < a);
-  (void)(pi > a);
-  (void)(pi <= a);
-  (void)(pi >= a);
-
-  (void)(b == pi);
-  (void)(b != pi);
-  (void)(b < pi);
-  (void)(b > pi);
-  (void)(b <= pi);
-  (void)(b >= pi);
-
-  (void)(pi == b);
-  (void)(pi != b);
-  (void)(pi < b);
-  (void)(pi > b);
-  (void)(pi <= b);
-  (void)(pi >= b);
-
-  (void)(b == b);
-  (void)(b != b);
-  (void)(b < b);
-  (void)(b > b);
-  (void)(b <= b);
-  (void)(b >= b);
-
-  (void)(pi == pi);
-  (void)(pi != pi);
-  (void)(pi < pi);
-  (void)(pi > pi);
-  (void)(pi <= pi);
-  (void)(pi >= pi);
-}
-
-// FIXME: This is wrong: the type T = 'const volatile int * const * const *'
-// would work here, and there exists a builtin candidate for that type.
-struct C { operator const int ***(); };
-void g(C c, volatile int ***p) {
-  (void)(c < p); // expected-error {{invalid operands}}
-}

Removed: cfe/trunk/test/CXX/over/over.built/p16.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/over/over.built/p16.cpp?rev=284810&view=auto
==============================================================================
--- cfe/trunk/test/CXX/over/over.built/p16.cpp (original)
+++ cfe/trunk/test/CXX/over/over.built/p16.cpp (removed)
@@ -1,75 +0,0 @@
-// RUN: %clang_cc1 -std=c++11 -verify %s -Wno-tautological-compare
-
-struct A { operator decltype(nullptr)(); };
-struct B { operator int A::*(); };
-void f(A a, B b, int A::*pi) {
-  (void)(a == a);
-  (void)(a != a);
-  (void)(a < a); // expected-error {{invalid operands}}
-  (void)(a > a); // expected-error {{invalid operands}}
-  (void)(a <= a); // expected-error {{invalid operands}}
-  (void)(a >= a); // expected-error {{invalid operands}}
-
-  (void)(a == b);
-  (void)(a != b);
-  (void)(a < b); // expected-error {{invalid operands}}
-  (void)(a > b); // expected-error {{invalid operands}}
-  (void)(a <= b); // expected-error {{invalid operands}}
-  (void)(a >= b); // expected-error {{invalid operands}}
-
-  (void)(b == a);
-  (void)(b != a);
-  (void)(b < a); // expected-error {{invalid operands}}
-  (void)(b > a); // expected-error {{invalid operands}}
-  (void)(b <= a); // expected-error {{invalid operands}}
-  (void)(b >= a); // expected-error {{invalid operands}}
-
-  (void)(a == pi);
-  (void)(a != pi);
-  (void)(a < pi); // expected-error {{invalid operands}}
-  (void)(a > pi); // expected-error {{invalid operands}}
-  (void)(a <= pi); // expected-error {{invalid operands}}
-  (void)(a >= pi); // expected-error {{invalid operands}}
-
-  (void)(pi == a);
-  (void)(pi != a);
-  (void)(pi < a); // expected-error {{invalid operands}}
-  (void)(pi > a); // expected-error {{invalid operands}}
-  (void)(pi <= a); // expected-error {{invalid operands}}
-  (void)(pi >= a); // expected-error {{invalid operands}}
-
-  (void)(b == pi);
-  (void)(b != pi);
-  (void)(b < pi); // expected-error {{invalid operands}}
-  (void)(b > pi); // expected-error {{invalid operands}}
-  (void)(b <= pi); // expected-error {{invalid operands}}
-  (void)(b >= pi); // expected-error {{invalid operands}}
-
-  (void)(pi == b);
-  (void)(pi != b);
-  (void)(pi < b); // expected-error {{invalid operands}}
-  (void)(pi > b); // expected-error {{invalid operands}}
-  (void)(pi <= b); // expected-error {{invalid operands}}
-  (void)(pi >= b); // expected-error {{invalid operands}}
-
-  (void)(b == b);
-  (void)(b != b);
-  (void)(b < b); // expected-error {{invalid operands}}
-  (void)(b > b); // expected-error {{invalid operands}}
-  (void)(b <= b); // expected-error {{invalid operands}}
-  (void)(b >= b); // expected-error {{invalid operands}}
-
-  (void)(pi == pi);
-  (void)(pi != pi);
-  (void)(pi < pi); // expected-error {{invalid operands}}
-  (void)(pi > pi); // expected-error {{invalid operands}}
-  (void)(pi <= pi); // expected-error {{invalid operands}}
-  (void)(pi >= pi); // expected-error {{invalid operands}}
-}
-
-// FIXME: This is wrong: type T = 'const volatile int * const A::* const B::*'
-// would work here, and there exists a builtin candidate for that type.
-struct C { operator const int *A::*B::*(); };
-void g(C c, volatile int *A::*B::*p) {
-  (void)(c == p); // expected-error {{invalid operands}}
-}

Modified: cfe/trunk/test/Misc/warning-flags.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/warning-flags.c?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/Misc/warning-flags.c (original)
+++ cfe/trunk/test/Misc/warning-flags.c Fri Oct 21 03:03:49 2016
@@ -18,7 +18,7 @@ This test serves two purposes:
 
 The list of warnings below should NEVER grow.  It should gradually shrink to 0.
 
-CHECK: Warnings without flags (83):
+CHECK: Warnings without flags (84):
 CHECK-NEXT:   ext_excess_initializers
 CHECK-NEXT:   ext_excess_initializers_in_char_array_initializer
 CHECK-NEXT:   ext_expected_semi_decl_list
@@ -31,6 +31,7 @@ CHECK-NEXT:   ext_plain_complex
 CHECK-NEXT:   ext_template_arg_extra_parens
 CHECK-NEXT:   ext_typecheck_comparison_of_pointer_integer
 CHECK-NEXT:   ext_typecheck_cond_incompatible_operands
+CHECK-NEXT:   ext_typecheck_cond_incompatible_operands_nonstandard
 CHECK-NEXT:   ext_typecheck_ordered_comparison_of_function_pointers
 CHECK-NEXT:   ext_typecheck_ordered_comparison_of_pointer_integer
 CHECK-NEXT:   ext_using_undefined_std

Modified: cfe/trunk/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/distribute_parallel_for_simd_aligned_messages.cpp Fri Oct 21 03:03:49 2016
@@ -166,8 +166,7 @@ template<class I, class C> int foomain(I
 
 #pragma omp target
 #pragma omp teams
-// FIXME: Should argc really be a pointer?
-#pragma omp distribute parallel for simd aligned (*argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+#pragma omp distribute parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   for (I k = 0; k < argc; ++k) ++k;
 
 #pragma omp target

Modified: cfe/trunk/test/OpenMP/distribute_simd_aligned_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/distribute_simd_aligned_messages.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/distribute_simd_aligned_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/distribute_simd_aligned_messages.cpp Fri Oct 21 03:03:49 2016
@@ -166,8 +166,7 @@ template<class I, class C> int foomain(I
 
 #pragma omp target
 #pragma omp teams
-// FIXME: Should argc really be a pointer?
-#pragma omp distribute simd aligned (*argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+#pragma omp distribute simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   for (I k = 0; k < argc; ++k) ++k;
 
 #pragma omp target

Modified: cfe/trunk/test/OpenMP/for_simd_aligned_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/for_simd_aligned_messages.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/for_simd_aligned_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/for_simd_aligned_messages.cpp Fri Oct 21 03:03:49 2016
@@ -121,8 +121,7 @@ template<class I, class C> int foomain(I
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (I k = 0; k < argc; ++k) ++k;
-// FIXME: Should argc really be a pointer?
-  #pragma omp for simd aligned (*argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  #pragma omp for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
   for (I k = 0; k < argc; ++k) ++k;

Modified: cfe/trunk/test/OpenMP/parallel_for_simd_aligned_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/parallel_for_simd_aligned_messages.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/parallel_for_simd_aligned_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/parallel_for_simd_aligned_messages.cpp Fri Oct 21 03:03:49 2016
@@ -121,8 +121,7 @@ template<class I, class C> int foomain(I
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (I k = 0; k < argc; ++k) ++k;
-// FIXME: Should argc really be a pointer?
-  #pragma omp parallel for simd aligned (*argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  #pragma omp parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp parallel for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
   for (I k = 0; k < argc; ++k) ++k;

Modified: cfe/trunk/test/OpenMP/simd_aligned_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/simd_aligned_messages.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/simd_aligned_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/simd_aligned_messages.cpp Fri Oct 21 03:03:49 2016
@@ -121,8 +121,7 @@ template<class I, class C> int foomain(I
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (I k = 0; k < argc; ++k) ++k;
-// FIXME: Should argc really be a pointer?
-  #pragma omp simd aligned (*argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  #pragma omp simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
   for (I k = 0; k < argc; ++k) ++k;

Modified: cfe/trunk/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/target_parallel_for_simd_aligned_messages.cpp Fri Oct 21 03:03:49 2016
@@ -121,8 +121,7 @@ template<class I, class C> int foomain(I
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp target parallel for simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (I k = 0; k < argc; ++k) ++k;
-// FIXME: Should argc really be a pointer?
-  #pragma omp target parallel for simd aligned (*argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  #pragma omp target parallel for simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp target parallel for simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
   for (I k = 0; k < argc; ++k) ++k;

Modified: cfe/trunk/test/OpenMP/target_simd_aligned_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/target_simd_aligned_messages.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/target_simd_aligned_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/target_simd_aligned_messages.cpp Fri Oct 21 03:03:49 2016
@@ -121,8 +121,7 @@ template<class I, class C> int foomain(I
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp target simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (I k = 0; k < argc; ++k) ++k;
-// FIXME: Should argc really be a pointer?
-  #pragma omp target simd aligned (*argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  #pragma omp target simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp target simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
   for (I k = 0; k < argc; ++k) ++k;

Modified: cfe/trunk/test/OpenMP/taskloop_simd_aligned_messages.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/OpenMP/taskloop_simd_aligned_messages.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/OpenMP/taskloop_simd_aligned_messages.cpp (original)
+++ cfe/trunk/test/OpenMP/taskloop_simd_aligned_messages.cpp Fri Oct 21 03:03:49 2016
@@ -121,8 +121,7 @@ template<class I, class C> int foomain(I
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp taskloop simd aligned (argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
   for (I k = 0; k < argc; ++k) ++k;
-// FIXME: Should argc really be a pointer?
-  #pragma omp taskloop simd aligned (*argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
+  #pragma omp taskloop simd aligned (argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name}}
   for (I k = 0; k < argc; ++k) ++k;
   #pragma omp taskloop simd aligned (argc : 5) // expected-warning {{aligned clause will be ignored because the requested alignment is not a power of 2}}
   for (I k = 0; k < argc; ++k) ++k;

Modified: cfe/trunk/test/SemaCXX/compare.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/compare.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/compare.cpp (original)
+++ cfe/trunk/test/SemaCXX/compare.cpp Fri Oct 21 03:03:49 2016
@@ -201,10 +201,9 @@ int test1(int i) {
 
 enum E { e };
 void test2(int i, void *vp) {
-  if (&i == vp) { } // ok
   if (test1 == vp) { } // expected-warning{{equality comparison between function pointer and void pointer}}
   if (test1 == e) { } // expected-error{{comparison between pointer and integer}}
-  if (vp < 0) { } // expected-error {{comparison between pointer and zero}}
+  if (vp < 0) { }
   if (test1 < e) { } // expected-error{{comparison between pointer and integer}}
 }
 

Modified: cfe/trunk/test/SemaCXX/composite-pointer-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/composite-pointer-type.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/composite-pointer-type.cpp (original)
+++ cfe/trunk/test/SemaCXX/composite-pointer-type.cpp Fri Oct 21 03:03:49 2016
@@ -53,8 +53,8 @@ bool f(Matrix4 m1, const Matrix4 m2) {
 
 // PR6346
 bool f1(bool b, void **p, const void **q) {
-  if (p == q)
+  if (p == q) // expected-warning{{comparison of distinct pointer types ('void **' and 'const void **') uses non-standard composite pointer type 'const void *const *'}}
     return false;
 
-  return b? p : q;
+  return b? p : q; // expected-warning{{incompatible operand types ('void **' and 'const void **') use non-standard composite pointer type 'const void *const *'}}
 }

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Fri Oct 21 03:03:49 2016
@@ -279,17 +279,17 @@ static_assert(&s.x > &s.y, "false"); //
 
 static_assert(0 == &y, "false"); // expected-error {{false}}
 static_assert(0 != &y, "");
-constexpr bool n3 = (int*)0 <= &y; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n4 = (int*)0 >= &y; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n5 = (int*)0 < &y; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n6 = (int*)0 > &y; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n3 = 0 <= &y; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n4 = 0 >= &y; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n5 = 0 < &y; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n6 = 0 > &y; // expected-error {{must be initialized by a constant expression}}
 
 static_assert(&x == 0, "false"); // expected-error {{false}}
 static_assert(&x != 0, "");
-constexpr bool n9 = &x <= (int*)0; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n10 = &x >= (int*)0; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n11 = &x < (int*)0; // expected-error {{must be initialized by a constant expression}}
-constexpr bool n12 = &x > (int*)0; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n9 = &x <= 0; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n10 = &x >= 0; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n11 = &x < 0; // expected-error {{must be initialized by a constant expression}}
+constexpr bool n12 = &x > 0; // expected-error {{must be initialized by a constant expression}}
 
 static_assert(&x == &x, "");
 static_assert(&x != &x, "false"); // expected-error {{false}}

Removed: cfe/trunk/test/SemaCXX/libstdcxx_libcxx_less_hack.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/libstdcxx_libcxx_less_hack.cpp?rev=284810&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/libstdcxx_libcxx_less_hack.cpp (original)
+++ cfe/trunk/test/SemaCXX/libstdcxx_libcxx_less_hack.cpp (removed)
@@ -1,67 +0,0 @@
-// This is a test for a hack in Clang that works around a problem introduced by
-// DR583: it's no longer possible to compare a pointer against nullptr_t, but
-// we still want to permit those comparisons within less<> and friends.
-
-// RUN: %clang_cc1 -verify %s -std=c++14
-
-namespace std {
-  template<typename T = void> struct less {};
-  template<typename T = void> struct less_equal {};
-  template<typename T = void> struct greater {};
-  template<typename T = void> struct greater_equal {};
-
-  template<> struct less<> {
-    template <class T1, class T2>
-    auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t < u))
-        -> decltype(t < u) {
-      return t < u;
-    }
-  };
-
-  template<> struct less_equal<> {
-    template <class T1, class T2>
-    auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t <= u))
-        -> decltype(t <= u) {
-      return t <= u;
-    }
-  };
-
-  template<> struct greater<> {
-    template <class T1, class T2>
-    auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t > u))
-        -> decltype(t > u) {
-      return t > u;
-    }
-  };
-
-  template<> struct greater_equal<> {
-    template <class T1, class T2>
-    auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t >= u))
-        -> decltype(t >= u) {
-      return t >= u;
-    }
-  };
-
-  template<typename = void> struct unrelated;
-  template<> struct unrelated<> {
-    template <class T1, class T2>
-    auto operator()(T1 &&t, T2 &&u) const noexcept(noexcept(t < u)) // expected-note {{substitution failure}}
-        -> decltype(t < u) {
-      return t < u;
-    }
-  };
-};
-
-void test(int *p) {
-  using namespace std;
-  less<>()(p, nullptr);
-  less<>()(nullptr, p);
-  less_equal<>()(p, nullptr);
-  less_equal<>()(nullptr, p);
-  greater<>()(p, nullptr);
-  greater<>()(nullptr, p);
-  greater_equal<>()(p, nullptr);
-  greater_equal<>()(nullptr, p);
-
-  unrelated<>()(p, nullptr); // expected-error {{no matching function}}
-}

Modified: cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp (original)
+++ cfe/trunk/test/SemaCXX/null_in_arithmetic_ops.cpp Fri Oct 21 03:03:49 2016
@@ -71,8 +71,8 @@ void f() {
   b = a == NULL || a != NULL; // expected-warning 2{{comparison between NULL and non-pointer ('int' and NULL)}}
   b = NULL == a || NULL != a; // expected-warning 2{{comparison between NULL and non-pointer (NULL and 'int')}}
 
-  b = &a < NULL || NULL < &a || &a > NULL || NULL > &a; // expected-error 4{{ordered comparison between pointer and zero}}
-  b = &a <= NULL || NULL <= &a || &a >= NULL || NULL >= &a; // expected-error 4{{ordered comparison between pointer and zero}}
+  b = &a < NULL || NULL < &a || &a > NULL || NULL > &a;
+  b = &a <= NULL || NULL <= &a || &a >= NULL || NULL >= &a;
   b = &a == NULL || NULL == &a || &a != NULL || NULL != &a;
 
   b = 0 == a;

Modified: cfe/trunk/test/SemaCXX/nullptr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nullptr.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nullptr.cpp (original)
+++ cfe/trunk/test/SemaCXX/nullptr.cpp Fri Oct 21 03:03:49 2016
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -ffreestanding -Wno-null-conversion -Wno-tautological-compare %s
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 -ffreestanding -Wno-null-conversion %s
 #include <stdint.h>
 
 typedef decltype(nullptr) nullptr_t;
@@ -32,17 +32,17 @@ nullptr_t f(nullptr_t null)
 
   // Operators
   (void)(null == nullptr);
-  (void)(null <= nullptr); // expected-error {{invalid operands to binary expression}}
+  (void)(null <= nullptr);
   (void)(null == 0);
   (void)(null == (void*)0);
   (void)((void*)0 == nullptr);
-  (void)(null <= 0); // expected-error {{invalid operands to binary expression}}
-  (void)(null <= (void*)0); // expected-error {{invalid operands to binary expression}}
-  (void)((void*)0 <= nullptr); // expected-error {{invalid operands to binary expression}}
+  (void)(null <= 0);
+  (void)(null <= (void*)0);
+  (void)((void*)0 <= nullptr);
   (void)(0 == nullptr);
   (void)(nullptr == 0);
-  (void)(nullptr <= 0); // expected-error {{invalid operands to binary expression}}
-  (void)(0 <= nullptr); // expected-error {{invalid operands to binary expression}}
+  (void)(nullptr <= 0);
+  (void)(0 <= nullptr);
   (void)(1 > nullptr); // expected-error {{invalid operands to binary expression}}
   (void)(1 != nullptr); // expected-error {{invalid operands to binary expression}}
   (void)(1 + nullptr); // expected-error {{invalid operands to binary expression}}
@@ -118,24 +118,24 @@ static_assert(__is_scalar(nullptr_t), ""
 static_assert(__is_pod(nullptr_t), "");
 static_assert(sizeof(nullptr_t) == sizeof(void*), "");
 
-static_assert(!(nullptr < nullptr), ""); // expected-error {{invalid operands to binary expression}}
-static_assert(!(nullptr > nullptr), ""); // expected-error {{invalid operands to binary expression}}
-static_assert(  nullptr <= nullptr, ""); // expected-error {{invalid operands to binary expression}}
-static_assert(  nullptr >= nullptr, ""); // expected-error {{invalid operands to binary expression}}
+static_assert(!(nullptr < nullptr), "");
+static_assert(!(nullptr > nullptr), "");
+static_assert(  nullptr <= nullptr, "");
+static_assert(  nullptr >= nullptr, "");
 static_assert(  nullptr == nullptr, "");
 static_assert(!(nullptr != nullptr), "");
 
-static_assert(!(0 < nullptr), ""); // expected-error {{invalid operands to binary expression}}
-static_assert(!(0 > nullptr), ""); // expected-error {{invalid operands to binary expression}}
-static_assert(  0 <= nullptr, ""); // expected-error {{invalid operands to binary expression}}
-static_assert(  0 >= nullptr, ""); // expected-error {{invalid operands to binary expression}}
+static_assert(!(0 < nullptr), "");
+static_assert(!(0 > nullptr), "");
+static_assert(  0 <= nullptr, "");
+static_assert(  0 >= nullptr, "");
 static_assert(  0 == nullptr, "");
 static_assert(!(0 != nullptr), "");
 
-static_assert(!(nullptr < 0), ""); // expected-error {{invalid operands to binary expression}}
-static_assert(!(nullptr > 0), ""); // expected-error {{invalid operands to binary expression}}
-static_assert(  nullptr <= 0, ""); // expected-error {{invalid operands to binary expression}}
-static_assert(  nullptr >= 0, ""); // expected-error {{invalid operands to binary expression}}
+static_assert(!(nullptr < 0), "");
+static_assert(!(nullptr > 0), "");
+static_assert(  nullptr <= 0, "");
+static_assert(  nullptr >= 0, "");
 static_assert(  nullptr == 0, "");
 static_assert(!(nullptr != 0), "");
 
@@ -154,10 +154,10 @@ namespace overloading {
   void test_conversion(ConvertsToNullPtr ctn) {
     (void)(ctn == ctn);
     (void)(ctn != ctn);
-    (void)(ctn <= ctn); // expected-error {{invalid operands to binary expression}}
-    (void)(ctn >= ctn); // expected-error {{invalid operands to binary expression}}
-    (void)(ctn < ctn); // expected-error {{invalid operands to binary expression}}
-    (void)(ctn > ctn); // expected-error {{invalid operands to binary expression}}
+    (void)(ctn <= ctn);
+    (void)(ctn >= ctn);
+    (void)(ctn < ctn);
+    (void)(ctn > ctn);
   }
 }
 

Modified: cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp (original)
+++ cfe/trunk/test/SemaCXX/nullptr_in_arithmetic_ops.cpp Fri Oct 21 03:03:49 2016
@@ -45,12 +45,12 @@ void foo() {
   b = a == nullptr || nullptr == a; // expected-error 2{{invalid operands to binary expression}}
   b = a != nullptr || nullptr != a; // expected-error 2{{invalid operands to binary expression}}
 
-  b = &a < nullptr || nullptr < &a || &a > nullptr || nullptr > &a; // expected-error 4{{invalid operands}}
-  b = &a <= nullptr || nullptr <= &a || &a >= nullptr || nullptr >= &a; // expected-error 4{{invalid operands}}
+  b = &a < nullptr || nullptr < &a || &a > nullptr || nullptr > &a;
+  b = &a <= nullptr || nullptr <= &a || &a >= nullptr || nullptr >= &a;
   b = &a == nullptr || nullptr == &a || &a != nullptr || nullptr != &a;
 
-  b = nullptr < nullptr || nullptr > nullptr; // expected-error 2{{invalid operands to binary expression}}
-  b = nullptr <= nullptr || nullptr >= nullptr; // expected-error 2{{invalid operands to binary expression}}
+  b = nullptr < nullptr || nullptr > nullptr;
+  b = nullptr <= nullptr || nullptr >= nullptr;
   b = nullptr == nullptr || nullptr != nullptr;
 
   b = ((nullptr)) != a;  // expected-error{{invalid operands to binary expression}}

Modified: cfe/trunk/test/SemaCXX/warn-memsize-comparison.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-memsize-comparison.cpp?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/warn-memsize-comparison.cpp (original)
+++ cfe/trunk/test/SemaCXX/warn-memsize-comparison.cpp Fri Oct 21 03:03:49 2016
@@ -5,7 +5,7 @@ typedef __SIZE_TYPE__ size_t;
 extern "C" void *memset(void *, int, size_t);
 extern "C" void *memmove(void *s1, const void *s2, size_t n);
 extern "C" void *memcpy(void *s1, const void *s2, size_t n);
-extern "C" int memcmp(void *s1, const void *s2, size_t n);
+extern "C" void *memcmp(void *s1, const void *s2, size_t n);
 extern "C" int strncmp(const char *s1, const char *s2, size_t n);
 extern "C" int strncasecmp(const char *s1, const char *s2, size_t n);
 extern "C" char *strncpy(char *dst, const char *src, size_t n);
@@ -28,12 +28,11 @@ void f() {
     expected-note {{explicitly cast the argument}}
   if (memmove(b1, b2, sizeof(b1)) == 0) {}
 
-  // FIXME: This fixit is bogus.
   if (memcpy(b1, b2, sizeof(b1) < 0)) {} // \
     expected-warning{{size argument in 'memcpy' call is a comparison}} \
     expected-note {{did you mean to compare}} \
     expected-note {{explicitly cast the argument}}
-  if (memcpy(b1, b2, sizeof(b1)) < 0) {} // expected-error {{ordered comparison between pointer and zero}}
+  if (memcpy(b1, b2, sizeof(b1)) < 0) {}
 
   if (memcmp(b1, b2, sizeof(b1) <= 0)) {} // \
     expected-warning{{size argument in 'memcmp' call is a comparison}} \
@@ -59,12 +58,11 @@ void f() {
     expected-note {{explicitly cast the argument}}
   if (strncpy(b1, b2, sizeof(b1)) == 0 || true) {}
 
-  // FIXME: This fixit is bogus.
   if (strncat(b1, b2, sizeof(b1) - 1 >= 0 && true)) {} // \
     expected-warning{{size argument in 'strncat' call is a comparison}} \
     expected-note {{did you mean to compare}} \
     expected-note {{explicitly cast the argument}}
-  if (strncat(b1, b2, sizeof(b1) - 1) >= 0 && true) {} // expected-error {{ordered comparison between pointer and zero}}
+  if (strncat(b1, b2, sizeof(b1) - 1) >= 0 && true) {}
 
   if (strndup(b1, sizeof(b1) != 0)) {} // \
     expected-warning{{size argument in 'strndup' call is a comparison}} \

Modified: cfe/trunk/test/SemaObjCXX/null_objc_pointer.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/null_objc_pointer.mm?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/null_objc_pointer.mm (original)
+++ cfe/trunk/test/SemaObjCXX/null_objc_pointer.mm Fri Oct 21 03:03:49 2016
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -Wnull-arithmetic %s
+// expected-no-diagnostics
 #define NULL __null
 
 @interface X
@@ -7,7 +8,7 @@
 void f() {
   bool b;
   X *d;
-  b = d < NULL || NULL < d || d > NULL || NULL > d; // expected-error 4{{ordered comparison between pointer and zero}}
-  b = d <= NULL || NULL <= d || d >= NULL || NULL >= d; // expected-error 4{{ordered comparison between pointer and zero}}
+  b = d < NULL || NULL < d || d > NULL || NULL > d;
+  b = d <= NULL || NULL <= d || d >= NULL || NULL >= d;
   b = d == NULL || NULL == d || d != NULL || NULL != d;
 }

Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=284811&r1=284810&r2=284811&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Fri Oct 21 03:03:49 2016
@@ -3541,7 +3541,7 @@ and <I>POD class</I></td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#583">583</a></td>
     <td>CD3</td>
     <td>Relational pointer comparisons against the null pointer constant</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="none" align="center">No</td>
   </tr>
   <tr id="584">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#584">584</a></td>
@@ -8887,7 +8887,7 @@ and <I>POD class</I></td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1512">1512</a></td>
     <td>CD3</td>
     <td>Pointer comparison vs qualification conversions</td>
-    <td class="svn" align="center">SVN</td>
+    <td class="none" align="center">Unknown</td>
   </tr>
   <tr class="open" id="1513">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1513">1513</a></td>




More information about the cfe-commits mailing list