r352540 - OpenCL: Use length modifier for warning on vector printf arguments

Matt Arsenault via cfe-commits cfe-commits at lists.llvm.org
Tue Jan 29 12:49:54 PST 2019


Author: arsenm
Date: Tue Jan 29 12:49:54 2019
New Revision: 352540

URL: http://llvm.org/viewvc/llvm-project?rev=352540&view=rev
Log:
OpenCL: Use length modifier for warning on vector printf arguments

Re-enable format string warnings on printf.

The warnings are still incomplete. Apparently it is undefined to use a
vector specifier without a length modifier, which is not currently
warned on. Additionally, type warnings appear to not be working with
the hh modifier, and aren't warning on all of the special restrictions
from c99 printf.

Modified:
    cfe/trunk/include/clang/AST/FormatString.h
    cfe/trunk/lib/AST/FormatString.cpp
    cfe/trunk/lib/AST/PrintfFormatString.cpp
    cfe/trunk/lib/AST/ScanfFormatString.cpp
    cfe/trunk/lib/Headers/opencl-c.h
    cfe/trunk/lib/Sema/SemaChecking.cpp
    cfe/trunk/test/Sema/format-strings.c
    cfe/trunk/test/SemaOpenCL/format-strings-fixit.cl
    cfe/trunk/test/SemaOpenCL/printf-format-string-warnings.cl
    cfe/trunk/test/SemaOpenCL/printf-format-strings.cl

Modified: cfe/trunk/include/clang/AST/FormatString.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/FormatString.h?rev=352540&r1=352539&r2=352540&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/FormatString.h (original)
+++ cfe/trunk/include/clang/AST/FormatString.h Tue Jan 29 12:49:54 2019
@@ -67,6 +67,7 @@ public:
     None,
     AsChar,       // 'hh'
     AsShort,      // 'h'
+    AsShortLong,  // 'hl' (OpenCL float/int vector element)
     AsLong,       // 'l'
     AsLongLong,   // 'll'
     AsQuad,       // 'q' (BSD, deprecated, for 64-bit integer types)
@@ -436,7 +437,8 @@ public:
 
   bool usesPositionalArg() const { return UsesPositionalArg; }
 
-  bool hasValidLengthModifier(const TargetInfo &Target) const;
+  bool hasValidLengthModifier(const TargetInfo &Target,
+                              const LangOptions &LO) const;
 
   bool hasStandardLengthModifier() const;
 

Modified: cfe/trunk/lib/AST/FormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/FormatString.cpp?rev=352540&r1=352539&r2=352540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/FormatString.cpp (original)
+++ cfe/trunk/lib/AST/FormatString.cpp Tue Jan 29 12:49:54 2019
@@ -223,6 +223,9 @@ clang::analyze_format_string::ParseLengt
       if (I != E && *I == 'h') {
         ++I;
         lmKind = LengthModifier::AsChar;
+      } else if (I != E && *I == 'l' && LO.OpenCL) {
+        ++I;
+        lmKind = LengthModifier::AsShortLong;
       } else {
         lmKind = LengthModifier::AsShort;
       }
@@ -487,7 +490,8 @@ ArgType::matchesType(ASTContext &C, Qual
 }
 
 ArgType ArgType::makeVectorType(ASTContext &C, unsigned NumElts) const {
-  if (K != SpecificTy) // Won't be a valid vector element type.
+  // Check for valid vector element types.
+  if (T.isNull())
     return ArgType::Invalid();
 
   QualType Vec = C.getExtVectorType(T, NumElts);
@@ -572,6 +576,8 @@ analyze_format_string::LengthModifier::t
     return "hh";
   case AsShort:
     return "h";
+  case AsShortLong:
+    return "hl";
   case AsLong: // or AsWideChar
     return "l";
   case AsLongLong:
@@ -707,13 +713,18 @@ void OptionalAmount::toString(raw_ostrea
   }
 }
 
-bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target) const {
+bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
+                                             const LangOptions &LO) const {
   switch (LM.getKind()) {
     case LengthModifier::None:
       return true;
 
     // Handle most integer flags
     case LengthModifier::AsShort:
+      // Length modifier only applies to FP vectors.
+      if (LO.OpenCL && CS.isDoubleArg())
+        return !VectorNumElts.isInvalid();
+
       if (Target.getTriple().isOSMSVCRT()) {
         switch (CS.getKind()) {
           case ConversionSpecifier::cArg:
@@ -752,8 +763,18 @@ bool FormatSpecifier::hasValidLengthModi
           return false;
       }
 
+    case LengthModifier::AsShortLong:
+      return LO.OpenCL && !VectorNumElts.isInvalid();
+
     // Handle 'l' flag
     case LengthModifier::AsLong: // or AsWideChar
+      if (CS.isDoubleArg()) {
+        // Invalid for OpenCL FP scalars.
+        if (LO.OpenCL && VectorNumElts.isInvalid())
+          return false;
+        return true;
+      }
+
       switch (CS.getKind()) {
         case ConversionSpecifier::dArg:
         case ConversionSpecifier::DArg:
@@ -764,14 +785,6 @@ bool FormatSpecifier::hasValidLengthModi
         case ConversionSpecifier::UArg:
         case ConversionSpecifier::xArg:
         case ConversionSpecifier::XArg:
-        case ConversionSpecifier::aArg:
-        case ConversionSpecifier::AArg:
-        case ConversionSpecifier::fArg:
-        case ConversionSpecifier::FArg:
-        case ConversionSpecifier::eArg:
-        case ConversionSpecifier::EArg:
-        case ConversionSpecifier::gArg:
-        case ConversionSpecifier::GArg:
         case ConversionSpecifier::nArg:
         case ConversionSpecifier::cArg:
         case ConversionSpecifier::sArg:
@@ -878,6 +891,7 @@ bool FormatSpecifier::hasStandardLengthM
     case LengthModifier::AsInt3264:
     case LengthModifier::AsInt64:
     case LengthModifier::AsWide:
+    case LengthModifier::AsShortLong: // ???
       return false;
   }
   llvm_unreachable("Invalid LengthModifier Kind!");

Modified: cfe/trunk/lib/AST/PrintfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/PrintfFormatString.cpp?rev=352540&r1=352539&r2=352540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/PrintfFormatString.cpp (original)
+++ cfe/trunk/lib/AST/PrintfFormatString.cpp Tue Jan 29 12:49:54 2019
@@ -315,7 +315,11 @@ static PrintfSpecifierResult ParsePrintf
     case 'f': k = ConversionSpecifier::fArg; break;
     case 'g': k = ConversionSpecifier::gArg; break;
     case 'i': k = ConversionSpecifier::iArg; break;
-    case 'n': k = ConversionSpecifier::nArg; break;
+    case 'n':
+      // Not handled, but reserved in OpenCL.
+      if (!LO.OpenCL)
+        k = ConversionSpecifier::nArg;
+      break;
     case 'o': k = ConversionSpecifier::oArg; break;
     case 'p': k = ConversionSpecifier::pArg; break;
     case 's': k = ConversionSpecifier::sArg; break;
@@ -486,10 +490,12 @@ ArgType PrintfSpecifier::getScalarArgTyp
         // GNU extension.
         return Ctx.LongLongTy;
       case LengthModifier::None:
+      case LengthModifier::AsShortLong:
         return Ctx.IntTy;
       case LengthModifier::AsInt32:
         return ArgType(Ctx.IntTy, "__int32");
-      case LengthModifier::AsChar: return ArgType::AnyCharTy;
+      case LengthModifier::AsChar:
+        return ArgType::AnyCharTy;
       case LengthModifier::AsShort: return Ctx.ShortTy;
       case LengthModifier::AsLong: return Ctx.LongTy;
       case LengthModifier::AsLongLong:
@@ -520,6 +526,7 @@ ArgType PrintfSpecifier::getScalarArgTyp
         // GNU extension.
         return Ctx.UnsignedLongLongTy;
       case LengthModifier::None:
+      case LengthModifier::AsShortLong:
         return Ctx.UnsignedIntTy;
       case LengthModifier::AsInt32:
         return ArgType(Ctx.UnsignedIntTy, "unsigned __int32");
@@ -549,6 +556,18 @@ ArgType PrintfSpecifier::getScalarArgTyp
     }
 
   if (CS.isDoubleArg()) {
+    if (!VectorNumElts.isInvalid()) {
+      switch (LM.getKind()) {
+      case LengthModifier::AsShort:
+        return Ctx.HalfTy;
+      case LengthModifier::AsShortLong:
+        return Ctx.FloatTy;
+      case LengthModifier::AsLong:
+      default:
+        return Ctx.DoubleTy;
+      }
+    }
+
     if (LM.getKind() == LengthModifier::AsLongDouble)
       return Ctx.LongDoubleTy;
     return Ctx.DoubleTy;
@@ -582,6 +601,8 @@ ArgType PrintfSpecifier::getScalarArgTyp
       case LengthModifier::AsInt64:
       case LengthModifier::AsWide:
         return ArgType::Invalid();
+      case LengthModifier::AsShortLong:
+        llvm_unreachable("only used for OpenCL which doesn not handle nArg");
     }
   }
 
@@ -760,10 +781,13 @@ bool PrintfSpecifier::fixType(QualType Q
   case BuiltinType::UInt:
   case BuiltinType::Int:
   case BuiltinType::Float:
+    LM.setKind(VectorNumElts.isInvalid() ?
+               LengthModifier::None : LengthModifier::AsShortLong);
+    break;
   case BuiltinType::Double:
-    LM.setKind(LengthModifier::None);
+    LM.setKind(VectorNumElts.isInvalid() ?
+               LengthModifier::None : LengthModifier::AsLong);
     break;
-
   case BuiltinType::Char_U:
   case BuiltinType::UChar:
   case BuiltinType::Char_S:
@@ -796,7 +820,7 @@ bool PrintfSpecifier::fixType(QualType Q
     namedTypeToLengthModifier(QT, LM);
 
   // If fixing the length modifier was enough, we might be done.
-  if (hasValidLengthModifier(Ctx.getTargetInfo())) {
+  if (hasValidLengthModifier(Ctx.getTargetInfo(), LangOpt)) {
     // If we're going to offer a fix anyway, make sure the sign matches.
     switch (CS.getKind()) {
     case ConversionSpecifier::uArg:

Modified: cfe/trunk/lib/AST/ScanfFormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ScanfFormatString.cpp?rev=352540&r1=352539&r2=352540&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ScanfFormatString.cpp (original)
+++ cfe/trunk/lib/AST/ScanfFormatString.cpp Tue Jan 29 12:49:54 2019
@@ -261,9 +261,10 @@ ArgType ScanfSpecifier::getArgType(ASTCo
         case LengthModifier::AsInt32:
         case LengthModifier::AsInt3264:
         case LengthModifier::AsWide:
+        case LengthModifier::AsShortLong:
           return ArgType::Invalid();
       }
-      llvm_unreachable("Unsupported LenghtModifier Type");
+      llvm_unreachable("Unsupported LengthModifier Type");
 
     // Unsigned int.
     case ConversionSpecifier::oArg:
@@ -301,9 +302,10 @@ ArgType ScanfSpecifier::getArgType(ASTCo
         case LengthModifier::AsInt32:
         case LengthModifier::AsInt3264:
         case LengthModifier::AsWide:
+        case LengthModifier::AsShortLong:
           return ArgType::Invalid();
       }
-      llvm_unreachable("Unsupported LenghtModifier Type");
+      llvm_unreachable("Unsupported LengthModifier Type");
 
     // Float.
     case ConversionSpecifier::aArg:
@@ -396,6 +398,7 @@ ArgType ScanfSpecifier::getArgType(ASTCo
         case LengthModifier::AsInt32:
         case LengthModifier::AsInt3264:
         case LengthModifier::AsWide:
+        case LengthModifier::AsShortLong:
           return ArgType::Invalid();
         }
 
@@ -501,7 +504,7 @@ bool ScanfSpecifier::fixType(QualType QT
     namedTypeToLengthModifier(PT, LM);
 
   // If fixing the length modifier was enough, we are done.
-  if (hasValidLengthModifier(Ctx.getTargetInfo())) {
+  if (hasValidLengthModifier(Ctx.getTargetInfo(), LangOpt)) {
     const analyze_scanf::ArgType &AT = getArgType(Ctx);
     if (AT.isValid() && AT.matchesType(Ctx, QT))
       return true;

Modified: cfe/trunk/lib/Headers/opencl-c.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Headers/opencl-c.h?rev=352540&r1=352539&r2=352540&view=diff
==============================================================================
--- cfe/trunk/lib/Headers/opencl-c.h (original)
+++ cfe/trunk/lib/Headers/opencl-c.h Tue Jan 29 12:49:54 2019
@@ -14469,7 +14469,7 @@ half16 __ovld __cnfn shuffle2(half16 x,
 #if __OPENCL_C_VERSION__ >= CL_VERSION_1_2
 // OpenCL v1.2 s6.12.13, v2.0 s6.13.13 - printf
 
-int printf(__constant const char* st, ...);
+int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2)));
 #endif
 
 // OpenCL v1.1 s6.11.3, v1.2 s6.12.14, v2.0 s6.13.14 - Image Read and Write Functions

Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=352540&r1=352539&r2=352540&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Jan 29 12:49:54 2019
@@ -7650,7 +7650,8 @@ CheckPrintfHandler::HandlePrintfSpecifie
             startSpecifier, specifierLen);
 
   // Check the length modifier is valid with the given conversion specifier.
-  if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo()))
+  if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo(),
+                                 S.getLangOpts()))
     HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
                                 diag::warn_format_nonsensical_length);
   else if (!FS.hasStandardLengthModifier())
@@ -8154,7 +8155,8 @@ bool CheckScanfHandler::HandleScanfSpeci
   }
 
   // Check the length modifier is valid with the given conversion specifier.
-  if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo()))
+  if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo(),
+                                 S.getLangOpts()))
     HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
                                 diag::warn_format_nonsensical_length);
   else if (!FS.hasStandardLengthModifier())

Modified: cfe/trunk/test/Sema/format-strings.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings.c?rev=352540&r1=352539&r2=352540&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings.c (original)
+++ cfe/trunk/test/Sema/format-strings.c Tue Jan 29 12:49:54 2019
@@ -617,6 +617,8 @@ void test_opencl_vector_format(int x) {
   printf("%v4d", x); // expected-warning{{invalid conversion specifier 'v'}}
   printf("%vd", x); // expected-warning{{invalid conversion specifier 'v'}}
   printf("%0vd", x); // expected-warning{{invalid conversion specifier 'v'}}
+  printf("%hlf", x); // expected-warning{{invalid conversion specifier 'l'}}
+  printf("%hld", x); // expected-warning{{invalid conversion specifier 'l'}}
 }
 
 // Test that we correctly merge the format in both orders.

Modified: cfe/trunk/test/SemaOpenCL/format-strings-fixit.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/format-strings-fixit.cl?rev=352540&r1=352539&r2=352540&view=diff
==============================================================================
--- cfe/trunk/test/SemaOpenCL/format-strings-fixit.cl (original)
+++ cfe/trunk/test/SemaOpenCL/format-strings-fixit.cl Tue Jan 29 12:49:54 2019
@@ -3,22 +3,72 @@
 // RUN: %clang_cc1 -cl-std=CL1.2 -fsyntax-only -pedantic -Wall -Werror %t
 // RUN: %clang_cc1 -cl-std=CL1.2 -E -o - %t | FileCheck %s
 
+typedef __attribute__((ext_vector_type(4))) char char4;
+typedef __attribute__((ext_vector_type(4))) short short4;
 typedef __attribute__((ext_vector_type(4))) int int4;
+typedef __attribute__((ext_vector_type(4))) unsigned int uint4;
 typedef __attribute__((ext_vector_type(8))) int int8;
+typedef __attribute__((ext_vector_type(4))) long long4;
+typedef __attribute__((ext_vector_type(4))) float float4;
+typedef __attribute__((ext_vector_type(4))) double double4;
 
 int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2)));
 
 
 void vector_fixits() {
   printf("%v4f", (int4) 123);
-  // CHECK: printf("%v4d", (int4) 123);
+  // CHECK: printf("%v4hld", (int4) 123);
 
   printf("%v8d", (int4) 123);
-  // CHECK: printf("%v4d", (int4) 123);
+  // CHECK: printf("%v4hld", (int4) 123);
 
   printf("%v4d", (int8) 123);
-  // CHECK: printf("%v8d", (int8) 123);
+  // CHECK: printf("%v8hld", (int8) 123);
 
   printf("%v4f", (int8) 123);
-  // CHECK: printf("%v8d", (int8) 123);
+  // CHECK: printf("%v8hld", (int8) 123);
+
+  printf("%v4ld", (int8) 123);
+  // CHECK: printf("%v8hld", (int8) 123);
+
+  printf("%v4hlf", (int4) 123);
+  // CHECK: printf("%v4hld", (int4) 123);
+
+  printf("%v8hld", (int4) 123);
+  // CHECK: printf("%v4hld", (int4) 123);
+
+  printf("%v4hld", (int8) 123);
+  // CHECK: printf("%v8hld", (int8) 123);
+
+  printf("%v4hlf", (int8) 123);
+  // CHECK: printf("%v8hld", (int8) 123);
+
+  printf("%v4hd", (int4) 123);
+  // CHECK: printf("%v4hld", (int4) 123);
+
+  printf("%v4hld", (short4) 123);
+  // CHECK: printf("%v4hd", (short4) 123);
+
+  printf("%v4ld", (short4) 123);
+  // CHECK: printf("%v4hd", (short4) 123);
+
+  printf("%v4hld", (long4) 123);
+  // CHECK: printf("%v4ld", (long4) 123);
+
+  printf("%v8f", (float4) 2.0f);
+  // CHECK: printf("%v4hlf", (float4) 2.0f);
+
+  printf("%v4f", (float4) 2.0f);
+  // CHECK: printf("%v4hlf", (float4) 2.0f);
+
+  printf("%v4lf", (double4) 2.0);
+  // CHECK: printf("%v4lf", (double4) 2.0);
+
+  /// FIXME: This should be fixed
+  printf("%v4hhd", (int4) 123);
+  // CHECK: printf("%v4hhd", (int4) 123);
+
+  /// FIXME: This should be fixed
+  printf("%v4hhd", (int8) 123);
+  // CHECK: printf("%v4hhd", (int8) 123);
 }

Modified: cfe/trunk/test/SemaOpenCL/printf-format-string-warnings.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/printf-format-string-warnings.cl?rev=352540&r1=352539&r2=352540&view=diff
==============================================================================
--- cfe/trunk/test/SemaOpenCL/printf-format-string-warnings.cl (original)
+++ cfe/trunk/test/SemaOpenCL/printf-format-string-warnings.cl Tue Jan 29 12:49:54 2019
@@ -1,14 +1,12 @@
 // RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0 -finclude-default-header
 
-// FIXME: Make sure warnings are produced based on printf format strings.
-
-// expected-no-diagnostics
+// Make sure warnings are produced based on printf format strings.
 
 kernel void format_string_warnings(__constant char* arg) {
 
-  printf("%d", arg);
+  printf("%d", arg); // expected-warning {{format specifies type 'int' but the argument has type '__constant char *'}}
 
-  printf("not enough arguments %d %d", 4);
+  printf("not enough arguments %d %d", 4); // expected-warning {{more '%' conversions than data arguments}}
 
-  printf("too many arguments", 4);
+  printf("too many arguments", 4); // expected-warning {{data argument not used by format string}}
 }

Modified: cfe/trunk/test/SemaOpenCL/printf-format-strings.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/printf-format-strings.cl?rev=352540&r1=352539&r2=352540&view=diff
==============================================================================
--- cfe/trunk/test/SemaOpenCL/printf-format-strings.cl (original)
+++ cfe/trunk/test/SemaOpenCL/printf-format-strings.cl Tue Jan 29 12:49:54 2019
@@ -1,22 +1,90 @@
 // RUN: %clang_cc1 -cl-std=CL1.2 -cl-ext=+cl_khr_fp64 -fsyntax-only -verify %s
 // RUN: %clang_cc1 -cl-std=CL1.2 -cl-ext=-cl_khr_fp64 -fsyntax-only -verify %s
 
+typedef __attribute__((ext_vector_type(4))) half half4;
+
 typedef __attribute__((ext_vector_type(2))) float float2;
 typedef __attribute__((ext_vector_type(4))) float float4;
 
+#ifdef cl_khr_fp64
+typedef __attribute__((ext_vector_type(4))) double double4;
+#endif
+
+typedef __attribute__((ext_vector_type(4))) char char4;
+typedef __attribute__((ext_vector_type(4))) unsigned char uchar4;
+
+typedef __attribute__((ext_vector_type(4))) short short4;
+typedef __attribute__((ext_vector_type(4))) unsigned short ushort4;
+
 typedef __attribute__((ext_vector_type(2))) int int2;
 typedef __attribute__((ext_vector_type(4))) int int4;
 typedef __attribute__((ext_vector_type(16))) int int16;
 
+typedef __attribute__((ext_vector_type(4))) long long4;
+typedef __attribute__((ext_vector_type(4))) unsigned int uint4;
+typedef __attribute__((ext_vector_type(4))) unsigned long ulong4;
+
 int printf(__constant const char* st, ...) __attribute__((format(printf, 1, 2)));
 
+
+#ifdef cl_khr_fp64
+kernel void format_v4f64(half4 arg_h, float4 arg_f, double4 arg_d)
+{
+  printf("%v4lf", arg_d);
+  printf("%v4lf", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+  printf("%v4lf", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+  printf("%v4lF", arg_d);
+  printf("%v4lF", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+  printf("%v4lF", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+  printf("%v4le", arg_d);
+  printf("%v4le", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+  printf("%v4le", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+  printf("%v4lE", arg_d);
+  printf("%v4lE", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+  printf("%v4lE", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+  printf("%v4lg", arg_d);
+  printf("%v4lg", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+  printf("%v4lg", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+  printf("%v4lG", arg_d);
+  printf("%v4lG", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+  printf("%v4lG", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+  printf("%v4la", arg_d);
+  printf("%v4la", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+  printf("%v4la", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+
+  printf("%v4lA", arg_d);
+  printf("%v4lA", arg_f); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+  printf("%v4lA", arg_h); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'half4' (vector of 4 'half' values)}}
+}
+
+kernel void format_v4f16(half4 arg_h, float4 arg_f, double4 arg_d)
+{
+  printf("%v4hf\n", arg_d); // expected-warning{{format specifies type '__fp16 __attribute__((ext_vector_type(4)))' but the argument has type 'double4' (vector of 4 'double' values)}}
+  printf("%v4hf\n", arg_f); // expected-warning{{format specifies type '__fp16 __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+  printf("%v4hf\n", arg_h);
+}
+
+kernel void no_length_modifier_scalar_fp(float f) {
+  printf("%hf", f); // expected-warning{{length modifier 'h' results in undefined behavior or no effect with 'f' conversion specifier}}
+  printf("%hlf", f); // expected-warning{{length modifier 'hl' results in undefined behavior or no effect with 'f' conversion specifier}}
+  printf("%lf", f); // expected-warning{{length modifier 'l' results in undefined behavior or no effect with 'f' conversion specifier}}
+}
+
+#endif
+
 kernel void format_v4f32(float4 arg)
 {
 #ifdef cl_khr_fp64
     printf("%v4f\n", arg); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
 
     // Precision modifier
-    printf("%.2v4f\n", arg); // expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
+    printf("%.2v4f\n", arg); //expected-warning{{format specifies type 'double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
 #else
     // FIXME: These should not warn, and the type should be expected to be float.
     printf("%v4f\n", arg);  // expected-warning {{double __attribute__((ext_vector_type(4)))' but the argument has type 'float4' (vector of 4 'float' values)}}
@@ -92,3 +160,52 @@ kernel void crash_on_s(int4 arg)
 {
     printf("%v4s\n", arg);
 }
+
+
+kernel void printf_int_length_modifiers(char4 arg_c, short4 arg_s, int4 arg_i, long4 arg_l, uchar4 arg_uc, ushort4 arg_us, uint4 arg_ui, ulong4 arg_ul) {
+  printf("%v4hhd", arg_c);
+  printf("%v4hhd", arg_s);
+  printf("%v4hhd", arg_i);
+  printf("%v4hhd", arg_l);
+
+  printf("%v4hd", arg_c); // expected-warning{{format specifies type 'short __attribute__((ext_vector_type(4)))' but the argument has type 'char4' (vector of 4 'char' values)}}
+  printf("%v4hd", arg_s);
+  printf("%v4hd", arg_i); // expected-warning{{format specifies type 'short __attribute__((ext_vector_type(4)))' but the argument has type 'int4' (vector of 4 'int' values)}}
+  printf("%v4hd", arg_l); // expected-warning{{format specifies type 'short __attribute__((ext_vector_type(4)))' but the argument has type 'long4' (vector of 4 'long' values)}}
+
+  printf("%v4hld", arg_c); // expected-warning{{format specifies type 'int __attribute__((ext_vector_type(4)))' but the argument has type 'char4' (vector of 4 'char' values)}}
+  printf("%v4hld", arg_s); // expected-warning{{format specifies type 'int __attribute__((ext_vector_type(4)))' but the argument has type 'short4' (vector of 4 'short' values)}}
+  printf("%v4hld", arg_i);
+  printf("%v4hld", arg_l); // expected-warning{{format specifies type 'int __attribute__((ext_vector_type(4)))' but the argument has type 'long4' (vector of 4 'long' values)}}
+
+  printf("%v4ld", arg_c); // expected-warning{{format specifies type 'long __attribute__((ext_vector_type(4)))' but the argument has type 'char4' (vector of 4 'char' values)}}
+  printf("%v4ld", arg_s); // expected-warning{{format specifies type 'long __attribute__((ext_vector_type(4)))' but the argument has type 'short4' (vector of 4 'short' values)}}
+  printf("%v4ld", arg_i); // expected-warning{{format specifies type 'long __attribute__((ext_vector_type(4)))' but the argument has type 'int4' (vector of 4 'int' values)}}
+  printf("%v4ld", arg_l);
+
+
+
+  printf("%v4hhu", arg_uc);
+  printf("%v4hhu", arg_us); // expected-warning{{format specifies type 'unsigned char __attribute__((ext_vector_type(4)))' but the argument has type 'ushort4' (vector of 4 'unsigned short' values)}}
+  printf("%v4hhu", arg_ui); // expected-warning{{format specifies type 'unsigned char __attribute__((ext_vector_type(4)))' but the argument has type 'uint4' (vector of 4 'unsigned int' values)}}
+  printf("%v4hhu", arg_ul); // expected-warning{{format specifies type 'unsigned char __attribute__((ext_vector_type(4)))' but the argument has type 'ulong4' (vector of 4 'unsigned long' values)}}
+
+  printf("%v4hu", arg_uc); // expected-warning{{format specifies type 'unsigned short __attribute__((ext_vector_type(4)))' but the argument has type 'uchar4' (vector of 4 'unsigned char' values)}}
+  printf("%v4hu", arg_us);
+  printf("%v4hu", arg_ui); // expected-warning{{format specifies type 'unsigned short __attribute__((ext_vector_type(4)))' but the argument has type 'uint4' (vector of 4 'unsigned int' values)}}
+  printf("%v4hu", arg_ul); // expected-warning{{format specifies type 'unsigned short __attribute__((ext_vector_type(4)))' but the argument has type 'ulong4' (vector of 4 'unsigned long' values)}}
+
+  printf("%v4hlu", arg_uc); // expected-warning{{format specifies type 'unsigned int __attribute__((ext_vector_type(4)))' but the argument has type 'uchar4' (vector of 4 'unsigned char' values)}}
+  printf("%v4hlu", arg_us); // expected-warning{{format specifies type 'unsigned int __attribute__((ext_vector_type(4)))' but the argument has type 'ushort4' (vector of 4 'unsigned short' values)}}
+  printf("%v4hlu", arg_ui);
+  printf("%v4hlu", arg_ul); // expected-warning{{format specifies type 'unsigned int __attribute__((ext_vector_type(4)))' but the argument has type 'ulong4' (vector of 4 'unsigned long' values)}}
+
+  printf("%v4lu", arg_uc); // expected-warning{{format specifies type 'unsigned long __attribute__((ext_vector_type(4)))' but the argument has type 'uchar4' (vector of 4 'unsigned char' values)}}
+  printf("%v4lu", arg_us); // expected-warning{{format specifies type 'unsigned long __attribute__((ext_vector_type(4)))' but the argument has type 'ushort4' (vector of 4 'unsigned short' values)}}
+  printf("%v4lu", arg_ui); // expected-warning{{format specifies type 'unsigned long __attribute__((ext_vector_type(4)))' but the argument has type 'uint4' (vector of 4 'unsigned int' values)}}
+  printf("%v4lu", arg_ul);
+
+
+  printf("%v4n", &arg_i); // expected-warning{{invalid conversion specifier 'n'}}
+  printf("%v4hln", &arg_i); // expected-warning{{invalid conversion specifier 'n'}}
+}




More information about the cfe-commits mailing list