82 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			82 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
// RUN: %clang_cc1 -fsyntax-only -verify -Wformat-nonliteral -pedantic %s
 | 
						|
 | 
						|
#include <stdarg.h>
 | 
						|
 | 
						|
extern "C" {
 | 
						|
extern int scanf(const char *restrict, ...);
 | 
						|
extern int printf(const char *restrict, ...);
 | 
						|
extern int vprintf(const char *restrict, va_list);
 | 
						|
}
 | 
						|
 | 
						|
@class NSString;
 | 
						|
 | 
						|
@interface Format
 | 
						|
+ (void)print:(NSString *)format, ... __attribute__((format(NSString, 1, 2)));
 | 
						|
@end
 | 
						|
 | 
						|
 | 
						|
namespace Templates {
 | 
						|
  template<typename T>
 | 
						|
  void my_uninstantiated_print(const T &arg) {
 | 
						|
    [Format print:@"%d", arg];
 | 
						|
  }
 | 
						|
 | 
						|
  template<typename T>
 | 
						|
  void my_print(const T &arg) {
 | 
						|
    [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}}
 | 
						|
  }
 | 
						|
 | 
						|
  void use_my_print() {
 | 
						|
    my_print("abc"); // expected-note {{requested here}}
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  template<typename T>
 | 
						|
  class UninstantiatedPrinter {
 | 
						|
  public:
 | 
						|
    static void print(const T &arg) {
 | 
						|
      [Format print:@"%d", arg]; // no-warning
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  template<typename T>
 | 
						|
  class Printer {
 | 
						|
  public:
 | 
						|
    void print(const T &arg) {
 | 
						|
      [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}}
 | 
						|
    }
 | 
						|
  };
 | 
						|
 | 
						|
  void use_class(Printer<const char *> &p) {
 | 
						|
    p.print("abc"); // expected-note {{requested here}}
 | 
						|
  }
 | 
						|
 | 
						|
 | 
						|
  template<typename T>
 | 
						|
  class UninstantiatedWrapper {
 | 
						|
  public:
 | 
						|
    class Printer {
 | 
						|
    public:
 | 
						|
      void print(const T &arg) {
 | 
						|
        [Format print:@"%d", arg]; // no-warning
 | 
						|
      }
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
  template<typename T>
 | 
						|
  class Wrapper {
 | 
						|
  public:
 | 
						|
    class Printer {
 | 
						|
    public:
 | 
						|
      void print(const T &arg) {
 | 
						|
        [Format print:@"%d", arg]; // expected-warning {{format specifies type 'int' but the argument has type 'const char *'}}
 | 
						|
      }
 | 
						|
    };
 | 
						|
  };
 | 
						|
 | 
						|
  void use_class(Wrapper<const char *>::Printer &p) {
 | 
						|
    p.print("abc"); // expected-note {{requested here}}
 | 
						|
  }
 | 
						|
}
 | 
						|
 |