Skip to content

Commit

Permalink
Annotate functions accepting formatted strings so that GCC and clang …
Browse files Browse the repository at this point in the history
…can check

whether arguments match the format.


git-svn-id: https://svn.r-project.org/R/trunk@85619 00db46b3-68df-0310-9c12-caf00c1e9a41
  • Loading branch information
kalibera committed Nov 24, 2023
1 parent 9f1fdbf commit f374bbf
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 19 deletions.
43 changes: 36 additions & 7 deletions src/include/Defn.h
Original file line number Diff line number Diff line change
Expand Up @@ -2129,7 +2129,12 @@ NORET void R_jumpctxt(RCNTXT *, int, SEXP);
SEXP ItemName(SEXP, R_xlen_t);

/* ../main/errors.c : */
NORET void errorcall_cpy(SEXP, const char *, ...);
NORET void errorcall_cpy(SEXP, const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
;

NORET void ErrorMessage(SEXP, int, ...);
void WarningMessage(SEXP, R_WARNING, ...);
SEXP R_GetTraceback(int); // including deparse()ing
Expand All @@ -2138,10 +2143,20 @@ NORET void R_signalErrorCondition(SEXP cond, SEXP call);
NORET void R_signalErrorConditionEx(SEXP cond, SEXP call, int exitOnly);
SEXP R_vmakeErrorCondition(SEXP call,
const char *classname, const char *subclassname,
int nextra, const char *format, va_list ap);
int nextra, const char *format, va_list ap)
#ifdef __GNUC__
__attribute__ ((format (printf, 5, 0)))
#endif
;

SEXP R_makeErrorCondition(SEXP call,
const char *classname, const char *subclassname,
int nextra, const char *format, ...);
int nextra, const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 5, 6)))
#endif
;

void R_setConditionField(SEXP cond, R_xlen_t idx, const char *name, SEXP val);
SEXP R_makeNotSubsettableError(SEXP x, SEXP call);
SEXP R_makeMissingSubscriptError(SEXP x, SEXP call);
Expand Down Expand Up @@ -2236,9 +2251,23 @@ char *mbcsTruncateToValid(char *s);
Rboolean utf8Valid(const char *str);
char *Rf_strchr(const char *s, int c);
char *Rf_strrchr(const char *s, int c);
int Rvsnprintf_mbcs(char *buf, size_t size, const char *format, va_list ap);
int Rsnprintf_mbcs(char *str, size_t size, const char *format, ...);
int Rasprintf_malloc(char **str, const char *fmt, ...);
int Rvsnprintf_mbcs(char *buf, size_t size, const char *format, va_list ap)
#ifdef __GNUC__
__attribute__ ((format (printf, 3, 0)))
#endif
;

int Rsnprintf_mbcs(char *str, size_t size, const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 3, 4)))
#endif
;

int Rasprintf_malloc(char **str, const char *fmt, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
;

SEXP fixup_NaRm(SEXP args); /* summary.c */
void invalidate_cached_recodings(void); /* from sysutils.c */
Expand Down Expand Up @@ -2297,7 +2326,7 @@ extern const char *locale2charset(const char *);
# endif
# define gettext_noop(String) String
# define N_(String) gettext_noop (String)
# else /* not NLS */
# else /* not NLS */
# define _(String) (String)
# define N_(String) String
# define ngettext(String, StringP, N) (N > 1 ? StringP: String)
Expand Down
14 changes: 12 additions & 2 deletions src/include/R_ext/Error.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,21 @@ extern "C" {
# define NORET
#endif

NORET void Rf_error(const char *, ...);
NORET void Rf_error(const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
;

NORET void UNIMPLEMENTED(const char *);
NORET void WrongArgCount(const char *);

void Rf_warning(const char *, ...);
void Rf_warning(const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
;

void R_ShowMessage(const char *s);


Expand Down
31 changes: 26 additions & 5 deletions src/include/R_ext/Print.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 1998-2019 The R Core Team
* Copyright (C) 1998-2023 The R Core Team
*
* This header file is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand Down Expand Up @@ -42,11 +42,32 @@ extern "C" {
# define R_VA_LIST va_list
#endif

void Rprintf(const char *, ...);
void REprintf(const char *, ...);
void Rprintf(const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
;

void REprintf(const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 2)))
#endif
;

#if !defined(__cplusplus) || defined R_USE_C99_IN_CXX
void Rvprintf(const char *, R_VA_LIST);
void REvprintf(const char *, R_VA_LIST);

void Rvprintf(const char *, R_VA_LIST)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 0)))
#endif
;

void REvprintf(const char *, R_VA_LIST)
#ifdef __GNUC__
__attribute__ ((format (printf, 1, 0)))
#endif
;

#endif

#ifdef __cplusplus
Expand Down
8 changes: 6 additions & 2 deletions src/include/Rconnections.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 2000-2020 The R Core Team.
* Copyright (C) 2000-2023 The R Core Team.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -72,7 +72,11 @@ typedef struct clpconn {
int Rconn_fgetc(Rconnection con);
int Rconn_ungetc(int c, Rconnection con);
size_t Rconn_getline(Rconnection con, char *buf, size_t bufsize);
int Rconn_printf(Rconnection con, const char *format, ...);
int Rconn_printf(Rconnection con, const char *format, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
;
Rconnection getConnection(int n);
Rconnection getConnection_no_err(int n);
Rboolean switch_stdout(int icon, int closeOnExit);
Expand Down
20 changes: 17 additions & 3 deletions src/include/Rinternals.h
Original file line number Diff line number Diff line change
Expand Up @@ -683,9 +683,23 @@ Rboolean R_HasFancyBindings(SEXP rho);

/* ../main/errors.c : */
/* needed for R_load/savehistory handling in front ends */
NORET void Rf_errorcall(SEXP, const char *, ...);
void Rf_warningcall(SEXP, const char *, ...);
void Rf_warningcall_immediate(SEXP, const char *, ...);
NORET void Rf_errorcall(SEXP, const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
;

void Rf_warningcall(SEXP, const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
;

void Rf_warningcall_immediate(SEXP, const char *, ...)
#ifdef __GNUC__
__attribute__ ((format (printf, 2, 3)))
#endif
;

/* Save/Load Interface */
#define R_XDR_DOUBLE_SIZE 8
Expand Down
8 changes: 8 additions & 0 deletions src/library/tools/R/check.R
Original file line number Diff line number Diff line change
Expand Up @@ -5730,6 +5730,14 @@ add_dummies <- function(dir, Log)
ex_re <- "(RcppEigen/include/Eigen)/.*\\[-Wtautological-compare\\]"
lines <- filtergrep(ex_re, lines, useBytes = TRUE)

## 2023-11: filter out format warnings (to be fixed upstream)
ex_re <- "(Rcpp/include/Rcpp)/.*\\[-Wformat"
lines <- filtergrep(ex_re, lines, useBytes = TRUE)

## 2023-11: filter out format warnings (to be fixed upstream)
ex_re <- "(rstan/io)/.*\\[-Wformat"
lines <- filtergrep(ex_re, lines, useBytes = TRUE)

## Filter out StanHeader warnings
ex_re <- "StanHeaders/.*\\[-Wunneeded-internal-declaration\\]"
lines <- filtergrep(ex_re, lines, useBytes = TRUE)
Expand Down

0 comments on commit f374bbf

Please sign in to comment.