c++ 호출 함수 포인터 비교에 대한 경고를 생성하는 방법은 무엇입니까?



함수포인터 구조체 (1)

어떤 컴파일러 옵션이나 도구 (Visual C ++, GCC, Clang 또는 기타의 일부)가 코드를 분석 할 수 있으며 위의 코드와 같이 함수 포인터를 어디에서 비교하고 있는지 말해 줄 수 있습니까?

그러한 컴파일러 옵션이 있는지 확실하지 않습니다.

그러나 그러한 도구가 있습니다. clang-tidy. clang-tidy에 대한 자신의 수표를 작성할 수 있습니다. 이 블로그 를 팔로우하면 실제로는 매우 쉽습니다. 특히 AST에는 이미 많은 수의 matchers가 있으며, 원하는 유스 케이스를 처리해야합니다.

이 같은 것이 작동하는 것 같습니다.

binaryOperator(
    anyOf(hasOperatorName("=="), hasOperatorName("!=")),
    hasLHS(ignoringImpCasts(declRefExpr(hasType(functionType())))),
    hasRHS(ignoringImpCasts(declRefExpr(hasType(functionType())))))

OP의 예를 나타내는 플래그는 다음과 같습니다.

fp.cxx:3:25: note: "root" binds here
int main(void) { return test1 == test2; }
                        ^~~~~~~~~~~~~~

이것은 OP 케이스를 위해 특별히 작동하지만 실제로 다른 모든 가능한 경우와 일치 시키려면 더 명확하게해야합니다.

const auto AnyFunc = ignoringImpCasts(declRefExpr(hasType(anyOf(
    functionType(),
    pointsTo(functionType()),
    references(functionType())))));

Finder->AddMatcher(binaryOperator(
    anyOf(hasOperatorName("=="), hasOperatorName("!=")),
    hasLHS(AnyFunc),
    hasRHS(AnyFunc)).bind("op"), this);

또는 그 효과에 가까운 것.

/OPT:ICF 에 의해 트리거되는 코드에 버그가 있음을 추적하는 데 영원히 걸렸습니다 /OPT:ICF :

/ OPT : ICF는 동일한 주소가 다른 함수 또는 읽기 전용 데이터 멤버 (/ Gy를 사용하여 컴파일 된 const 변수)에 할당 될 수 있기 때문에 함수 또는 읽기 전용 데이터 멤버의 고유 주소에 의존하는 프로그램을 중단시킬 수 있습니다 .

(나는 링커가 동일한 함수를 버렸을 때 중단되는 평등을위한 함수 포인터를 저장하고 비교하고 있었다.)

이제 나는 그런 일을했을지도 모르는 모든 곳을 찾아야합니다.

테스트 케이스는 물론 사소한 것입니다 :

//MSVC: /Gy /link /OPT:ICF
int test1(void) { return 0; }
int test2(void) { return 0; }
int main(void) { return test1 == test2; }

나는 시험해 보았습니다 -Weverything , -pedantic -Weverything , -pedantic -Weverything , -pedantic -Weverything 등. 그러나 그들 중 누구도 경고를 내지 않습니다.

어떤 컴파일러 옵션이나 도구 (Visual C ++, GCC, Clang 또는 기타의 일부)가 코드를 분석 할 수 있으며 위의 코드와 같이 함수 포인터를 어디에서 비교하고 있는지 말해 줄 수 있습니까?





comdat-folding