brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.4 KiB · f1dc5ed Raw
229 lines · cpp
1// RUN: %check_clang_tidy -std=c++14 %s bugprone-signal-handler %t -- -- -isystem %clang_tidy_headers -isystem %S/Inputs/signal-handler -target x86_64-unknown-unknown2// FIXME: Fix the checker to work in C++17 or later mode.3#include "stdcpp.h"4#include "stdio.h"5 6// Functions called "signal" that are different from the system version.7typedef void (*callback_t)(int);8void signal(int, callback_t, int);9namespace ns {10void signal(int, callback_t);11}12 13extern "C" void handler_unsafe(int) {14  printf("xxx");15}16 17extern "C" void handler_unsafe_1(int) {18  printf("xxx");19}20 21namespace test_invalid_handler {22 23void handler_non_extern_c(int) {24  printf("xxx");25}26 27struct A {28  static void handler_member(int) {29    printf("xxx");30  }31};32 33void test() {34  std::signal(SIGINT, handler_unsafe_1);35  // CHECK-MESSAGES: :[[@LINE-17]]:3: warning: standard function 'printf' may not be asynchronous-safe; calling it from a signal handler may be dangerous [bugprone-signal-handler]36  // CHECK-MESSAGES: :[[@LINE-2]]:23: note: function 'handler_unsafe_1' registered here as signal handler37 38  std::signal(SIGINT, handler_non_extern_c);39  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: functions without C linkage are not allowed as signal handler (until C++17) [bugprone-signal-handler]40  std::signal(SIGINT, A::handler_member);41  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: functions without C linkage are not allowed as signal handler (until C++17) [bugprone-signal-handler]42  std::signal(SIGINT, [](int) { printf("xxx"); });43  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: lambda function is not allowed as signal handler (until C++17) [bugprone-signal-handler]44 45  // This case is (deliberately) not found by the checker.46  std::signal(SIGINT, [](int) -> callback_t { return &handler_unsafe; }(1));47}48 49} // namespace test_invalid_handler50 51namespace test_non_standard_signal_call {52 53struct Signal {54  static void signal(int, callback_t);55};56 57void test() {58  // No diagnostics here. All these signal calls differ from the standard system one.59  signal(SIGINT, handler_unsafe, 1);60  ns::signal(SIGINT, handler_unsafe);61  Signal::signal(SIGINT, handler_unsafe);62  system_other::signal(SIGINT, handler_unsafe);63}64 65} // namespace test_non_standard_signal_call66 67namespace test_cpp_construct_in_handler {68 69struct Struct {70  virtual ~Struct() {}71  void f1();72  int *begin();73  int *end();74  static void f2();75};76struct Derived : public Struct {77};78 79struct X {80  X(int, float);81};82 83Struct *S_Global;84const Struct *S_GlobalConst;85 86void f_non_extern_c() {87}88 89void f_default_arg(int P1 = 0) {90}91 92extern "C" void handler_cpp(int) {93  using namespace ::test_cpp_construct_in_handler;94 95  // These calls are not found as problems.96  // (Called functions are not analyzed if the current function has already97  // other problems.)98  f_non_extern_c();99  Struct::f2();100  // 'auto' is not disallowed101  auto Auto = 28u;102 103  Struct S;104  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]105  // CHECK-MESSAGES: :[[@LINE-2]]:10: remark: internally, the statement is parsed as a 'CXXConstructExpr'106  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler107  S_Global->f1();108  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]109  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXMemberCallExpr'110  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler111  const Struct &SRef = Struct();112  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]113  // CHECK-MESSAGES: :[[@LINE-2]]:24: remark: internally, the statement is parsed as a 'CXXBindTemporaryExpr'114  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler115  X(3, 4.4);116  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]117  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXTemporaryObjectExpr'118  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler119 120  auto L = [](int i) { printf("%d", i); };121  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]122  // CHECK-MESSAGES: :[[@LINE-2]]:12: remark: internally, the statement is parsed as a 'CXXConstructExpr'123  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler124  L(2);125  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]126  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXOperatorCallExpr'127  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler128 129  try {130    // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]131    // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXTryStmt'132    // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler133    int A;134  } catch (int) {135  };136  // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]137  // CHECK-MESSAGES: :[[@LINE-3]]:5: remark: internally, the statement is parsed as a 'CXXCatchStmt'138  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler139 140  throw(12);141  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]142  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXThrowExpr'143  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler144 145  for (int I : S) {146  }147  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]148  // CHECK-MESSAGES: :[[@LINE-3]]:3: remark: internally, the statement is parsed as a 'CXXForRangeStmt'149  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler150  // CHECK-MESSAGES: :[[@LINE-5]]:14: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]151  // CHECK-MESSAGES: :[[@LINE-6]]:14: remark: internally, the statement is parsed as a 'CXXMemberCallExpr'152  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler153 154  int Int = *(reinterpret_cast<int *>(&S));155  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]156  // CHECK-MESSAGES: :[[@LINE-2]]:15: remark: internally, the statement is parsed as a 'CXXReinterpretCastExpr'157  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler158  Int = static_cast<int>(12.34);159  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]160  // CHECK-MESSAGES: :[[@LINE-2]]:9: remark: internally, the statement is parsed as a 'CXXStaticCastExpr'161  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler162  Derived *Der = dynamic_cast<Derived *>(S_Global);163  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]164  // CHECK-MESSAGES: :[[@LINE-2]]:18: remark: internally, the statement is parsed as a 'CXXDynamicCastExpr'165  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler166  Struct *SPtr = const_cast<Struct *>(S_GlobalConst);167  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]168  // CHECK-MESSAGES: :[[@LINE-2]]:18: remark: internally, the statement is parsed as a 'CXXConstCastExpr'169  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler170  Int = int(12.34);171  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]172  // CHECK-MESSAGES: :[[@LINE-2]]:9: remark: internally, the statement is parsed as a 'CXXFunctionalCastExpr'173  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler174 175  int *IPtr = new int[10];176  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]177  // CHECK-MESSAGES: :[[@LINE-2]]:15: remark: internally, the statement is parsed as a 'CXXNewExpr'178  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler179  delete[] IPtr;180  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]181  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXDeleteExpr'182  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler183  IPtr = nullptr;184  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]185  // CHECK-MESSAGES: :[[@LINE-2]]:10: remark: internally, the statement is parsed as a 'CXXNullPtrLiteralExpr'186  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler187  bool Bool = true;188  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]189  // CHECK-MESSAGES: :[[@LINE-2]]:15: remark: internally, the statement is parsed as a 'CXXBoolLiteralExpr'190  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler191  f_default_arg();192  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]193  // CHECK-MESSAGES: :[[@LINE-2]]:3: remark: internally, the statement is parsed as a 'CXXDefaultArgExpr'194  // CHECK-MESSAGES: :198:23: note: function 'handler_cpp' registered here as signal handler195}196 197void test() {198  std::signal(SIGINT, handler_cpp);199}200 201} // namespace test_cpp_construct_in_handler202 203namespace test_cpp_indirect {204 205void non_extern_c() {206  int *P = nullptr;207}208 209extern "C" void call_cpp_indirect() {210  int *P = nullptr;211  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: C++-only construct is not allowed in signal handler (until C++17) [bugprone-signal-handler]212  // CHECK-MESSAGES: :[[@LINE-2]]:12: remark: internally, the statement is parsed as a 'CXXNullPtrLiteralExpr'213  // CHECK-MESSAGES: :[[@LINE+8]]:3: note: function 'call_cpp_indirect' called here from 'handler_cpp_indirect'214  // CHECK-MESSAGES: :[[@LINE+11]]:23: note: function 'handler_cpp_indirect' registered here as signal handler215}216 217extern "C" void handler_cpp_indirect(int) {218  non_extern_c();219  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: functions without C linkage are not allowed as signal handler (until C++17) [bugprone-signal-handler]220  // CHECK-MESSAGES: :[[@LINE+5]]:23: note: function 'handler_cpp_indirect' registered here as signal handler221  call_cpp_indirect();222}223 224void test() {225  std::signal(SIGINT, handler_cpp_indirect);226}227 228} // namespace test_cpp_indirect229