Home | History | Annotate | Download | only in SemaObjCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -pedantic %s
      2 
      3 #include <stdarg.h>
      4 
      5 extern "C" {
      6 extern int scanf(const char *restrict, ...);
      7 extern int printf(const char *restrict, ...);
      8 extern int vprintf(const char *restrict, va_list);
      9 }
     10 
     11 @class NSString;
     12 
     13 @interface Format
     14 + (void)print:(NSString *)format, ... __attribute__((format(NSString, 1, 2)));
     15 @end
     16 
     17 
     18 namespace Templates {
     19   template<typename T>
     20   void my_uninstantiated_print(const T &arg) {
     21     [Format print:@"%d", arg];
     22   }
     23 
     24   template<typename T>
     25   void my_print(const T &arg) {
     26     [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}}
     27   }
     28 
     29   void use_my_print() {
     30     my_print("abc"); // expected-note {{requested here}}
     31   }
     32 
     33 
     34   template<typename T>
     35   class UninstantiatedPrinter {
     36   public:
     37     static void print(const T &arg) {
     38       [Format print:@"%d", arg]; // no-warning
     39     }
     40   };
     41 
     42   template<typename T>
     43   class Printer {
     44   public:
     45     void print(const T &arg) {
     46       [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}}
     47     }
     48   };
     49 
     50   void use_class(Printer<const char *> &p) {
     51     p.print("abc"); // expected-note {{requested here}}
     52   }
     53 
     54 
     55   template<typename T>
     56   class UninstantiatedWrapper {
     57   public:
     58     class Printer {
     59     public:
     60       void print(const T &arg) {
     61         [Format print:@"%d", arg]; // no-warning
     62       }
     63     };
     64   };
     65 
     66   template<typename T>
     67   class Wrapper {
     68   public:
     69     class Printer {
     70     public:
     71       void print(const T &arg) {
     72         [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}}
     73       }
     74     };
     75   };
     76 
     77   void use_class(Wrapper<const char *>::Printer &p) {
     78     p.print("abc"); // expected-note {{requested here}}
     79   }
     80 }
     81 
     82