From 34f5c8c5aea5822fde4c5e162d7b019ed9182dde Mon Sep 17 00:00:00 2001 From: Kim Grasman Date: Sun, 12 Apr 2020 22:39:42 +0200 Subject: [PATCH] Add more complete testing for operator new This replaces builtins_new_included.cc with operator_new.cc, and covers all variants of operator new that do _not_ require to be included: - Raw explicit ::operator new/::operator delete calls - New expressions, both of builtin and user-defined types - Aligned allocation (currently disabled, as we misdiagnose it, see PR #777). --- run_iwyu_tests.py | 2 + tests/cxx/builtins_new_included.cc | 31 ----------- tests/cxx/operator_new.cc | 85 ++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 31 deletions(-) delete mode 100644 tests/cxx/builtins_new_included.cc create mode 100644 tests/cxx/operator_new.cc diff --git a/run_iwyu_tests.py b/run_iwyu_tests.py index f312a4438..c3ebf3ea9 100755 --- a/run_iwyu_tests.py +++ b/run_iwyu_tests.py @@ -113,6 +113,7 @@ def setUp(self): self.Include('macro_defined_by_includer-prefix.h')], 'macro_location.cc': ['-Wno-sizeof-pointer-div'], 'ms_inline_asm.cc': ['-fms-extensions'], + 'operator_new.cc': ['-std=c++17'], 'placement_new.cc': ['-std=c++17'], 'prefix_header_attribution.cc': [self.Include('prefix_header_attribution-d1.h')], 'prefix_header_includes_add.cc': prefix_headers, @@ -181,6 +182,7 @@ def setUp(self): 'no_fwd_decls.cc': ['.'], 'no_h_includes_cc.cc': ['.'], 'non_transitive_include.cc': ['.'], + 'operator_new.cc': ['.'], 'overloaded_class.cc': ['.'], 'pch_in_code.cc': ['.'], 'pointer_arith.cc': ['.'], diff --git a/tests/cxx/builtins_new_included.cc b/tests/cxx/builtins_new_included.cc deleted file mode 100644 index 76efc7b2c..000000000 --- a/tests/cxx/builtins_new_included.cc +++ /dev/null @@ -1,31 +0,0 @@ -//===--- builtins_new_included.cc - test input file for iwyu --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// Test that iwyu suggests the include for be removed if only -// built-in functions are used. - -#include - -void foo() { - char* ch = new char; - delete ch; - int* int_array = new int[10]; - delete[] int_array; -} - -/**** IWYU_SUMMARY - -tests/cxx/builtins_new_included.cc should add these lines: - -tests/cxx/builtins_new_included.cc should remove these lines: -- #include // lines XX-XX - -The full include-list for tests/cxx/builtins_new_included.cc: - -***** IWYU_SUMMARY */ diff --git a/tests/cxx/operator_new.cc b/tests/cxx/operator_new.cc new file mode 100644 index 000000000..b6676cb5a --- /dev/null +++ b/tests/cxx/operator_new.cc @@ -0,0 +1,85 @@ +//===--- operator_new.cc - test input file for iwyu -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +// Test that iwyu suggests the include for be removed if only +// built-in functions are used. + +#include +#include "tests/cxx/direct.h" + +// The most primitive ::operator new/delete are builtins, and are basically +// wrappers around malloc. +void ExplicitOperators() { + // IWYU: IndirectClass needs a declaration + // IWYU: IndirectClass is...*indirect.h + IndirectClass* elem = (IndirectClass*)::operator new(sizeof(IndirectClass)); + ::operator delete(elem); + + // IWYU: IndirectClass needs a declaration + // IWYU: IndirectClass is...*indirect.h + IndirectClass* arr = (IndirectClass*)::operator new[](4 * sizeof(IndirectClass)); + ::operator delete[](arr); +} + +// New- and delete-expressions, unless using placement syntax, only use builtin +// operators. They're equivalent with the above, but also run ctors/dtors. +// For placement syntax, see tests/cxx/placement_new.cc +void ExpressionsBuiltinTypes() { + char* elem = new char; + delete elem; + + int* arr = new int[4]; + delete[] arr; +} + +// New- and delete-expressions with user-defined types. +void ExpressionsUserTypes() { + // IWYU: IndirectClass needs a declaration + // IWYU: IndirectClass is...*indirect.h + IndirectClass* elem = new IndirectClass; + // IWYU: IndirectClass is...*indirect.h + delete elem; + + // IWYU: IndirectClass needs a declaration + // IWYU: IndirectClass is...*indirect.h + IndirectClass* arr = new IndirectClass[4]; + // IWYU: IndirectClass is...*indirect.h + delete[] arr; +} + +#if 0 +// Aligned allocation uses operator new(size_t, std::align_val_t) under the +// hood in C++17, but does not require to be included for it. Pre-C++17, +// the alignment is just ignored. +void ImplicitAlignedAllocation() { + struct alignas(32) Aligned { + float value[8]; + }; + + Aligned* elem = new Aligned; + delete elem; + + Aligned* arr = new Aligned[10]; + delete[] arr; +} +#endif + +/**** IWYU_SUMMARY + +tests/cxx/operator_new.cc should add these lines: +#include "tests/cxx/indirect.h" + +tests/cxx/operator_new.cc should remove these lines: +- #include // lines XX-XX +- #include "tests/cxx/direct.h" // lines XX-XX + +The full include-list for tests/cxx/operator_new.cc: +#include "tests/cxx/indirect.h" // for IndirectClass + +***** IWYU_SUMMARY */