Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The C Standard identifies five two distinct situations in which undefined behavior (UB) may arise as a result of invoking a function using a declaration that is incompatible with its definition or by supplying incorrect types or numbers of arguments:

UBDescription

2625

A pointer is used to call a function whose type is not compatible with the referenced type (6.3.2.3).

37

A function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function

38

For a call to a function without a function prototype in scope, the number of arguments does not equal the number of parameters (6.5.2.2).

39

For a call to a function without a function prototype in scope where the function is defined with a function prototype, either the prototype ends with an ellipsis or the types of the arguments after promotion are not compatible with the types of the parameters (6.5.2.2).

40

For a call to a function without a function prototype in scope where the function is not defined with a function prototype, the types of the arguments after promotion are not compatible with those of the parameters after promotion (with certain exceptions) (6.5.2.2).

41

A function is defined with a type that is not compatible with the type (of the expression) pointed to by the expression that denotes the called function (6.5.2.2).

Functions that are appropriately declared (as in DCL40-C. Do not create incompatible declarations of the same function or object) will typically generate a compiler diagnostic message if they are supplied with the wrong number or types of arguments. However, there are cases in which supplying the incorrect arguments to a function will, at best, generate compiler warnings. Although such warnings should be resolved, they do not prevent program compilation. (See MSC00-C. Compile cleanly at high warning levels.)

Noncompliant Code Example

The header <tgmath.h> provides type-generic macros for math functions. Although most functions from the <math.h> header have a complex counterpart in <complex.h>, several functions do not. Calling any of the following type-generic functions with complex values is undefined behavior.

Functions That Should Not Be Called with Complex Values

Functions that are appropriately declared (as in DCL40-C. Do not create incompatible declarations of the same function or object) will typically generate a compiler diagnostic message if they are supplied with the wrong number or types of arguments. However, there are cases in which supplying the incorrect arguments to a function will, at best, generate compiler warnings. Although such warnings should be resolved, they do not prevent program compilation. (See MSC00-C. Compile cleanly at high warning levels.)

Noncompliant Code Example

The header <tgmath.h> provides type-generic macros for math functions. Although most functions from the <math.h> header have a complex counterpart in <complex.h>, several functions do not. Calling any of the following type-generic functions with complex values is undefined behavior 205.

Functions That Should Not Be Called with Complex Values

atan2()erf()fdim()fmin()ilogb()llround()logb()nextafter()atan2()erf()fdim()fmin()ilogb()llround()logb()nextafter()rint()tgamma()
cbrt()erfc()floor()fmod()ldexp()log10()lrint()nexttoward()round()trunc()
ceil()exp2()fma()frexp()lgamma()log1p()lround()remainder()scalbn()
copysign()expm1()fmax()hypot()llrint()log2()nearbyint()remquo()scalbln()

...

In this noncompliant example, the C standard library function strchr() is called through the function pointer fp declared with a prototype with incorrectly typed arguments. According to the C Standard, 6.3.2.3, paragraph 8 [ISO/IEC 9899:20112024]

A pointer to a function of one type may be converted to a pointer to a function of another type and back again; the result shall compare equal to the original pointer. If a converted pointer is used to call a function whose type is not compatible with the referenced the referenced type, the behavior is undefined.

See undefined behavior 2625.

Code Block
bgColor#FFCCCC
langc
#include <stdio.h>
#include <string.h>

char *(*fp)();

int main(void) {
  const char *c;
  fp = strchr;
  c = fp('e', "Hello");
  printf("%s\n", c);
  return 0;
}

...

Calling a function with incorrect arguments can result in unexpected or unintended program behavior.

Rule

Severity

Likelihood

Detectable

RepairableRemediation Cost

Priority

Level

EXP37-C

Medium

Probable

No

HighNo

P4

L3

Automated Detection

() example described earlierPartially implementedRuleCheckerRuleCheckerPartially checked
ToolVersionCheckerDescription
Astrée
Include Page
Astrée_V
Astrée_V

incompatible-argument-type

parameter-match

parameter-match-computed

parameter-match-type

Fully checked
Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-EXP37
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

LANG.FUNCS.APM

Array parameter mismatch
Compass/ROSE

Can detect some violations of this rule. In particular, it ensures that all calls to open() supply exactly two arguments if the second argument does not involve O_CREAT, and exactly three arguments if the second argument does involve O_CREAT

Coverity
Include Page
Coverity_V
Coverity_V

MISRA C 2012 Rule 8.2

MISRA C 2012 Rule 17.3

Implemented

Relies on functions declared with prototypes, allow compiler to checkcheck

Cppcheck Premium

Include Page
Cppcheck Premium_V
Cppcheck Premium_V

premium-cert-exp37-c

ECLAIR

Include Page
ECLAIR_V
ECLAIR_V

CC2.EXP37

Partially implemented

EDG


GCC
Include Page
GCC_V
GCC_V

Can detect violation of this rule when the -Wstrict-prototypes flag is used. However, it cannot detect violations involving variadic functions, such as the open

Klocwork
Include Page
Klocwork_VKlocwork_VMISRA.FUNC.UNMATCHED.PARAMSLDRA tool suite
Include Page
LDRA_VLDRA_V

41 D, 21 S, 98 S, 170 S, 496 S, 576 S

Partially implementedParasoft C/C++test
Include Page
Parasoft_VParasoft_V

CERT_C-EXP37-a
CERT_C-EXP37-b
CERT_C-EXP37-c
CERT_C-EXP37-d

Identifiers shall be given for all of the parameters in a function prototype declaration
Function types shall have named parameters
Function types shall be in prototype form
Functions shall always have visible prototype at the function call

() example described earlier

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C1331, C1332, C1333, C3002, C3320, C3335

C++0403


Klocwork
Include Page
Klocwork_V
Klocwork_V
MISRA.FUNC.UNMATCHED.PARAMS
LDRA tool suite
Include Page
LDRA_V
LDRA_V

41 D, 21 S, 98 S, 170 S, 496 S, 576 S

Partially implemented
Parasoft C/C++test

Include Page
Parasoft_V
Parasoft_V

CERT_C-EXP37-a
CERT_C-EXP37-b
CERT_C-EXP37-d

Conversions shall not be performed between non compatible pointer to a function types
Specify the access permission bits if a file is created using the 'open' or 'openat' system call
Functions shall always have visible prototype at the function call

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rule EXP37-C

Checks for:

  • Implicit function declaration
  • Bad file access mode or status
  • Unreliable cast of function pointer
  • Standard function call with incorrect arguments

Rule partially covered.

Polyspace Bug Finder
Include Page
Polyspace Bug Finder_VPolyspace Bug Finder_V

Bad file access mode or status

Declaration mismatch

Format string specifiers and arguments mismatch

Qualifier removed in conversion

Standard function call with incorrect arguments

Unreliable cast of function pointer

MISRA C:2012 Rule 8.3

MISRA C:2012 Rule 11.1

MISRA C:2012 Rule 17.3

Access mode argument of function in fopen or open group is invalid

Mismatch between function or variable declarations

String specifiers do not match corresponding arguments

Variable qualifier is lost during conversion

Argument to a standard function does not meet requirements for use in the function

Function pointer cast to another function pointer with different argument or return type

All declarations of an object or function shall use the same names and type qualifiers

Conversions shall not be performed between a pointer to a function and any other type

A function shall not be declared implicitly

PRQA QA-C++4.1 0403PRQA QA-C
Include Page
PRQA QA-C_vPRQA QA-C_v1331, 1332, 1333, 3002, 3320, 3335

PVS-Studio

Include Page
PVS-Studio_V
PVS-Studio_V

V540, V541, V549, V575, V632, V639, V666, V671, V742, V743, V764, V1004
Security Reviewer - Static Reviewer

Include Page
Security Reviewer - Static Reviewer_V
Security Reviewer - Static Reviewer_V

C71Fully implemented
SonarQube C/C++ Plugin
Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V
S930Detects incorrect argument count
RuleChecker

Include Page
RuleChecker_V
RuleChecker_V

parameter-match

parameter-match-type

Partially checked
TrustInSoft Analyzer

Include Page

TrustInSoft Analyzer_V

TrustInSoft Analyzer_V

parameter-match

parameter-match-type

unclassified ("function type matches")Partially verified (see one compliant and one non-compliant example).

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

...

  • Wrong argument values or references


Bibliography

[CVE]CVE-2006-1174
[ISO/IEC 9899:2011]6.35.2.32, "Pointers"Function Calls"
[ISO/IEC 9899:2024]6.53.2.23, "Function CallsPointers"
[IEEE Std 1003.1:2013]open()
[Spinellis 2006]Section 2.6.1, "Incorrect Routine or Arguments"

...