From 131067f7ff95f829b723267dbc9c7b4597b33b29 Mon Sep 17 00:00:00 2001 From: Zach Anderson Date: Sun, 6 Feb 2022 14:17:53 -0800 Subject: [PATCH] Add clang-analyzer-* and clang-diagnostic-* to .clang-tidy --- .clang-tidy | 11 ++++- common/graphics/persistent_cache.cc | 3 ++ display_list/display_list_benchmarks.cc | 41 ++++++++++--------- flow/paint_utils.cc | 3 ++ fml/platform/android/jni_util.cc | 13 +++--- fml/platform/android/message_loop_android.cc | 2 +- fml/platform/android/scoped_java_ref.cc | 17 +++++--- .../waitable_event_unittest.cc | 5 +++ lib/ui/compositing/scene_builder_unittests.cc | 5 +++ lib/ui/hooks_unittests.cc | 5 +++ lib/ui/painting/image_encoding_unittests.cc | 5 +++ lib/ui/painting/multi_frame_codec.cc | 3 ++ runtime/dart_isolate.cc | 2 + runtime/dart_isolate_unittests.cc | 5 +++ .../no_dart_plugin_registrant_unittests.cc | 5 +++ runtime/type_conversions_unittests.cc | 5 +++ shell/common/animator_unittests.cc | 5 +++ shell/common/dart_native_benchmarks.cc | 5 +++ shell/common/input_events_unittests.cc | 9 +++- shell/common/shell_unittests.cc | 6 +++ shell/platform/android/android_context_gl.cc | 2 +- .../android/android_image_generator.cc | 8 ++-- .../android/android_image_generator.h | 11 +++-- shell/platform/android/android_surface_gl.cc | 2 +- shell/platform/common/json_message_codec.cc | 4 +- .../common/json_message_codec_unittests.cc | 1 + shell/platform/common/json_method_codec.cc | 1 + .../common/json_method_codec_unittests.cc | 1 + .../ios/framework/Source/FlutterEngine.mm | 2 + .../Source/FlutterTextInputPlugin.mm | 1 - .../darwin/ios/ios_render_target_gl.mm | 2 +- .../Source/FlutterEmbedderKeyResponder.mm | 2 +- .../FlutterEmbedderKeyResponderUnittests.mm | 2 +- .../framework/Source/FlutterEngineTest.mm | 7 +++- .../Source/FlutterOpenGLRendererTest.mm | 5 +++ .../FlutterPlatformNodeDelegateMacTest.mm | 10 ++++- .../embedder/tests/embedder_a11y_unittests.cc | 5 +++ .../embedder/tests/embedder_unittests.cc | 5 +++ .../embedder/tests/embedder_unittests_gl.cc | 5 +++ .../tests/embedder_unittests_metal.mm | 5 +++ shell/platform/glfw/key_event_handler.cc | 1 + .../linux/fl_basic_message_channel_test.cc | 3 ++ shell/platform/linux/fl_engine_test.cc | 5 +++ testing/mock_canvas.cc | 2 - 44 files changed, 191 insertions(+), 56 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index a8ad73bfd8abc..3586b8001573d 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,13 +1,20 @@ # Prefix check with "-" to ignore. Checks: "google-*,\ +clang-analyzer-*,\ +clang-diagnostic-*,\ -google-objc-global-variable-declaration,\ --google-objc-avoid-throwing-exception" +-google-objc-avoid-throwing-exception,\ +-clang-analyzer-nullability.NullPassedToNonnull,\ +-clang-analyzer-nullability.NullablePassedToNonnull,\ +-clang-analyzer-nullability.NullReturnedFromNonnull,\ +-clang-analyzer-nullability.NullableReturnedFromNonnull" # Only warnings treated as errors are reported # in the "ci/lint.sh" script and pre-push git hook. # Add checks when all warnings are fixed # to prevent new warnings being introduced. # https://github.com/flutter/flutter/issues/93279 -WarningsAsErrors: "clang-analyzer-osx.*,\ +WarningsAsErrors: "clang-analyzer-*,\ +clang-diagnostic-*,\ google-objc-*,\ google-explicit-constructor" diff --git a/common/graphics/persistent_cache.cc b/common/graphics/persistent_cache.cc index 5c38120bd5b2f..7af4ec8e992f3 100644 --- a/common/graphics/persistent_cache.cc +++ b/common/graphics/persistent_cache.cc @@ -191,6 +191,9 @@ sk_sp ParseBase64(const std::string& input) { } size_t PersistentCache::PrecompileKnownSkSLs(GrDirectContext* context) const { + // clang-tidy has trouble reasoning about some of the complicated array and + // pointer-arithmetic code in rapidjson. + // NOLINTNEXTLINE(clang-analyzer-cplusplus.PlacementNew) auto known_sksls = LoadSkSLs(); // A trace must be present even if no precompilations have been completed. FML_TRACE_EVENT("flutter", "PersistentCache::PrecompileKnownSkSLs", "count", diff --git a/display_list/display_list_benchmarks.cc b/display_list/display_list_benchmarks.cc index 3ca1035e15705..0960649e914c5 100644 --- a/display_list/display_list_benchmarks.cc +++ b/display_list/display_list_benchmarks.cc @@ -114,7 +114,7 @@ void BM_DrawLine(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -162,7 +162,7 @@ void BM_DrawRect(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -207,7 +207,7 @@ void BM_DrawOval(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -254,7 +254,7 @@ void BM_DrawCircle(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -331,7 +331,7 @@ void BM_DrawRRect(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -412,7 +412,7 @@ void BM_DrawDRRect(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -464,7 +464,7 @@ void BM_DrawArc(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -482,7 +482,7 @@ std::vector GetPolygonPoints(size_t n, SkPoint center, SkScalar r) { float angle; float full_circle = 2.0f * M_PI; for (size_t i = 0; i < n; i++) { - angle = (full_circle / (float)n) * (float)i; + angle = (full_circle / static_cast(n)) * static_cast(i); x = center.x() + r * std::cosf(angle); y = center.y() + r * std::sinf(angle); points.push_back(SkPoint::Make(x, y)); @@ -666,7 +666,7 @@ void BM_DrawPath(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -709,12 +709,13 @@ sk_sp GetTestVertices(SkPoint center, colors.push_back(SK_ColorCYAN); for (size_t i = 0; i <= outer_points.size(); i++) { vertices.push_back(outer_points[i % outer_points.size()]); - if (i % 3 == 0) + if (i % 3 == 0) { colors.push_back(SK_ColorRED); - else if (i % 3 == 1) + } else if (i % 3 == 1) { colors.push_back(SK_ColorGREEN); - else + } else { colors.push_back(SK_ColorBLUE); + } } break; case SkVertices::VertexMode::kTriangles_VertexMode: @@ -810,7 +811,7 @@ void BM_DrawVertices(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -913,7 +914,7 @@ void BM_DrawPoints(benchmark::State& state, auto display_list = builder.Build(); - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -987,7 +988,7 @@ void BM_DrawImage(benchmark::State& state, auto display_list = builder.Build(); - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -1069,7 +1070,7 @@ void BM_DrawImageRect(benchmark::State& state, auto display_list = builder.Build(); - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -1153,7 +1154,7 @@ void BM_DrawImageNine(benchmark::State& state, auto display_list = builder.Build(); - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -1226,7 +1227,7 @@ void BM_DrawTextBlob(benchmark::State& state, auto display_list = builder.Build(); - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -1290,7 +1291,7 @@ void BM_DrawShadow(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } @@ -1343,7 +1344,7 @@ void BM_SaveLayer(benchmark::State& state, auto display_list = builder.Build(); // We only want to time the actual rasterization. - for (auto _ : state) { + for ([[maybe_unused]] auto _ : state) { display_list->RenderTo(canvas); canvas_provider->GetSurface()->flushAndSubmit(true); } diff --git a/flow/paint_utils.cc b/flow/paint_utils.cc index 647ca3da0bae4..ea6704a06827c 100644 --- a/flow/paint_utils.cc +++ b/flow/paint_utils.cc @@ -37,8 +37,11 @@ void DrawCheckerboard(SkCanvas* canvas, const SkRect& rect) { canvas->save(); canvas->clipRect(rect); + // Secure random number generation isn't needed here. + // NOLINTBEGIN(clang-analyzer-security.insecureAPI.rand) auto checkerboard_color = SkColorSetARGB(64, rand() % 256, rand() % 256, rand() % 256); + // NOLINTEND(clang-analyzer-security.insecureAPI.rand) DrawCheckerboard(canvas, checkerboard_color, 0x00000000, 12); canvas->restore(); diff --git a/fml/platform/android/jni_util.cc b/fml/platform/android/jni_util.cc index 86942d20e9f8d..e3b0d0342190e 100644 --- a/fml/platform/android/jni_util.cc +++ b/fml/platform/android/jni_util.cc @@ -52,7 +52,7 @@ JNIEnv* AttachCurrentThread() { } else { args.name = thread_name; } - jint ret = g_jvm->AttachCurrentThread(&env, &args); + [[maybe_unused]] jint ret = g_jvm->AttachCurrentThread(&env, &args); FML_DCHECK(JNI_OK == ret); FML_DCHECK(tls_jni_detach.get() == nullptr); @@ -182,9 +182,10 @@ ScopedJavaLocalRef VectorToBufferArray( env->NewObjectArray(vector.size(), byte_buffer_clazz.obj(), NULL); ASSERT_NO_EXCEPTION(); for (size_t i = 0; i < vector.size(); ++i) { + uint8_t* data = const_cast(vector[i].data()); ScopedJavaLocalRef item( - env, - env->NewDirectByteBuffer((void*)(vector[i].data()), vector[i].size())); + env, env->NewDirectByteBuffer(reinterpret_cast(data), + vector[i].size())); env->SetObjectArrayElement(java_array, i, item.obj()); } return ScopedJavaLocalRef(env, java_array); @@ -195,16 +196,18 @@ bool HasException(JNIEnv* env) { } bool ClearException(JNIEnv* env) { - if (!HasException(env)) + if (!HasException(env)) { return false; + } env->ExceptionDescribe(); env->ExceptionClear(); return true; } bool CheckException(JNIEnv* env) { - if (!HasException(env)) + if (!HasException(env)) { return true; + } jthrowable exception = env->ExceptionOccurred(); env->ExceptionClear(); diff --git a/fml/platform/android/message_loop_android.cc b/fml/platform/android/message_loop_android.cc index c45160d6d6d14..b4c5982181a54 100644 --- a/fml/platform/android/message_loop_android.cc +++ b/fml/platform/android/message_loop_android.cc @@ -83,7 +83,7 @@ void MessageLoopAndroid::Terminate() { } void MessageLoopAndroid::WakeUp(fml::TimePoint time_point) { - bool result = TimerRearm(timer_fd_.get(), time_point); + [[maybe_unused]] bool result = TimerRearm(timer_fd_.get(), time_point); FML_DCHECK(result); } diff --git a/fml/platform/android/scoped_java_ref.cc b/fml/platform/android/scoped_java_ref.cc index 2900379219206..31a027a4a071e 100644 --- a/fml/platform/android/scoped_java_ref.cc +++ b/fml/platform/android/scoped_java_ref.cc @@ -13,13 +13,14 @@ namespace jni { static const int kDefaultLocalFrameCapacity = 16; ScopedJavaLocalFrame::ScopedJavaLocalFrame(JNIEnv* env) : env_(env) { - int failed = env_->PushLocalFrame(kDefaultLocalFrameCapacity); + [[maybe_unused]] int failed = + env_->PushLocalFrame(kDefaultLocalFrameCapacity); FML_DCHECK(!failed); } ScopedJavaLocalFrame::ScopedJavaLocalFrame(JNIEnv* env, int capacity) : env_(env) { - int failed = env_->PushLocalFrame(capacity); + [[maybe_unused]] int failed = env_->PushLocalFrame(capacity); FML_DCHECK(!failed); } @@ -43,10 +44,12 @@ JNIEnv* JavaRef::SetNewLocalRef(JNIEnv* env, jobject obj) { } else { FML_DCHECK(env == AttachCurrentThread()); // Is |env| on correct thread. } - if (obj) + if (obj) { obj = env->NewLocalRef(obj); - if (obj_) + } + if (obj_) { env->DeleteLocalRef(obj_); + } obj_ = obj; return env; } @@ -57,10 +60,12 @@ void JavaRef::SetNewGlobalRef(JNIEnv* env, jobject obj) { } else { FML_DCHECK(env == AttachCurrentThread()); // Is |env| on correct thread. } - if (obj) + if (obj) { obj = env->NewGlobalRef(obj); - if (obj_) + } + if (obj_) { env->DeleteGlobalRef(obj_); + } obj_ = obj; } diff --git a/fml/synchronization/waitable_event_unittest.cc b/fml/synchronization/waitable_event_unittest.cc index dde70ad598fe0..5e5c8137c2256 100644 --- a/fml/synchronization/waitable_event_unittest.cc +++ b/fml/synchronization/waitable_event_unittest.cc @@ -15,6 +15,9 @@ #include "flutter/fml/macros.h" #include "gtest/gtest.h" +// rand() is only used for tests in this file. +// NOLINTBEGIN(clang-analyzer-security.insecureAPI.rand) + namespace fml { namespace { @@ -183,3 +186,5 @@ TEST(ManualResetWaitableEventTest, SignalMultiple) { } // namespace } // namespace fml + +// NOLINTEND(clang-analyzer-security.insecureAPI.rand) diff --git a/lib/ui/compositing/scene_builder_unittests.cc b/lib/ui/compositing/scene_builder_unittests.cc index b87f9b5776396..8148dd902db4d 100644 --- a/lib/ui/compositing/scene_builder_unittests.cc +++ b/lib/ui/compositing/scene_builder_unittests.cc @@ -13,6 +13,9 @@ #include "flutter/shell/common/thread_host.h" #include "flutter/testing/testing.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -156,3 +159,5 @@ TEST_F(ShellTest, EngineLayerDisposeReleasesReference) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/lib/ui/hooks_unittests.cc b/lib/ui/hooks_unittests.cc index 6cee7e6f3c286..d9d019e4f9f1d 100644 --- a/lib/ui/hooks_unittests.cc +++ b/lib/ui/hooks_unittests.cc @@ -12,6 +12,9 @@ #include "flutter/testing/testing.h" #include "third_party/dart/runtime/include/dart_api.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -82,3 +85,5 @@ TEST_F(HooksTest, HooksUnitTests) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/lib/ui/painting/image_encoding_unittests.cc b/lib/ui/painting/image_encoding_unittests.cc index e4d50465fc9ab..59b5fe51730c4 100644 --- a/lib/ui/painting/image_encoding_unittests.cc +++ b/lib/ui/painting/image_encoding_unittests.cc @@ -14,6 +14,9 @@ #include "flutter/testing/testing.h" #include "gmock/gmock.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -167,3 +170,5 @@ TEST_F(ShellTest, EncodeImageAccessesSyncSwitch) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/lib/ui/painting/multi_frame_codec.cc b/lib/ui/painting/multi_frame_codec.cc index 07c341953e8d9..a46cbcbf0a85b 100644 --- a/lib/ui/painting/multi_frame_codec.cc +++ b/lib/ui/painting/multi_frame_codec.cc @@ -219,6 +219,9 @@ Dart_Handle MultiFrameCodec::getNextFrame(Dart_Handle callback_handle) { })); return Dart_Null(); + // The static leak checker gets confused by the control flow, unique pointers + // and closures in this function. + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) } int MultiFrameCodec::frameCount() const { diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc index d60404d9a7e38..85c8f05f5d022 100644 --- a/runtime/dart_isolate.cc +++ b/runtime/dart_isolate.cc @@ -1008,9 +1008,11 @@ Dart_Isolate DartIsolate::CreateDartIsolateGroup( { // Ownership of the isolate data objects has been transferred to the Dart // VM. + // NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks) std::shared_ptr embedder_isolate(*isolate_data); isolate_group_data.release(); isolate_data.release(); + // NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks) success = InitializeIsolate(std::move(embedder_isolate), isolate, error); } diff --git a/runtime/dart_isolate_unittests.cc b/runtime/dart_isolate_unittests.cc index f1fe951696854..0bf7dd0da1756 100644 --- a/runtime/dart_isolate_unittests.cc +++ b/runtime/dart_isolate_unittests.cc @@ -17,6 +17,9 @@ #include "third_party/tonic/converter/dart_converter.h" #include "third_party/tonic/scopes/dart_isolate_scope.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -566,3 +569,5 @@ TEST_F(DartIsolateTest, DartPluginRegistrantIsCalled) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/runtime/no_dart_plugin_registrant_unittests.cc b/runtime/no_dart_plugin_registrant_unittests.cc index 7869830a1b7d0..0027e7973a34e 100644 --- a/runtime/no_dart_plugin_registrant_unittests.cc +++ b/runtime/no_dart_plugin_registrant_unittests.cc @@ -11,6 +11,9 @@ #include "flutter/testing/fixture_test.h" #include "flutter/testing/testing.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -71,3 +74,5 @@ TEST_F(DartIsolateTest, DartPluginRegistrantIsNotPresent) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/runtime/type_conversions_unittests.cc b/runtime/type_conversions_unittests.cc index ea4aed66d5d4d..650066ed2fd3d 100644 --- a/runtime/type_conversions_unittests.cc +++ b/runtime/type_conversions_unittests.cc @@ -8,6 +8,9 @@ #include "flutter/testing/testing.h" #include "flutter/third_party/tonic/converter/dart_converter.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -172,3 +175,5 @@ TEST_F(TypeConversionsTest, CanConvertListOfFloatsToListOfDartDoubles) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/common/animator_unittests.cc b/shell/common/animator_unittests.cc index e09d5a07d8184..57fad157af38d 100644 --- a/shell/common/animator_unittests.cc +++ b/shell/common/animator_unittests.cc @@ -15,6 +15,9 @@ #include "flutter/testing/testing.h" #include "gtest/gtest.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -183,3 +186,5 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyIdleBeforeRender) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/common/dart_native_benchmarks.cc b/shell/common/dart_native_benchmarks.cc index c9875a0d8b0d5..30a08a4f879f2 100644 --- a/shell/common/dart_native_benchmarks.cc +++ b/shell/common/dart_native_benchmarks.cc @@ -12,6 +12,9 @@ #include "fml/synchronization/count_down_latch.h" #include "runtime/dart_vm_lifecycle.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter::testing { class DartNativeBenchmarks : public DartFixture, public benchmark::Fixture { @@ -101,3 +104,5 @@ BENCHMARK_F(DartNativeBenchmarks, MultipleDartToNativeMessages) } } // namespace flutter::testing + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/common/input_events_unittests.cc b/shell/common/input_events_unittests.cc index f7514beabc4b5..3f117c006c65f 100644 --- a/shell/common/input_events_unittests.cc +++ b/shell/common/input_events_unittests.cc @@ -5,6 +5,9 @@ #include "flutter/shell/common/shell_test.h" #include "flutter/testing/testing.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -275,7 +278,9 @@ TEST_F(ShellTest, HandlesActualIphoneXsInputEvents) { // We don't use `constexpr int frame_time` here because MSVC doesn't handle // it well with lambda capture. UnitlessTime frame_time = 10000; - for (double base_latency_f = 0; base_latency_f < 1; base_latency_f += 0.1) { + double base_latency_f = 0.0; + for (int i = 0; i < 10; i++) { + base_latency_f += 0.1; // Everything is converted to int to avoid floating point error in // TestSimulatedInputEvents. UnitlessTime base_latency = @@ -414,3 +419,5 @@ TEST_F(ShellTest, CanCorrectlySynthesizePointerPacket) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 843b3c0a699da..e63778523e5ca 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -40,6 +40,9 @@ #include "flutter/vulkan/vulkan_application.h" // nogncheck #endif +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -1907,6 +1910,7 @@ TEST_F(ShellTest, CanConvertToAndFromMappings) { const size_t buffer_size = 2 << 20; uint8_t* buffer = static_cast(::malloc(buffer_size)); + // NOLINTNEXTLINE(clang-analyzer-unix.Malloc) ASSERT_TRUE(buffer != nullptr); ASSERT_TRUE(MemsetPatternSetOrCheck( buffer, buffer_size, MemsetPatternOp::kMemsetPatternOpSetBuffer)); @@ -3444,3 +3448,5 @@ TEST_F(ShellTest, UsesPlatformMessageHandler) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/platform/android/android_context_gl.cc b/shell/platform/android/android_context_gl.cc index 75ae7b804f578..c70136d23c864 100644 --- a/shell/platform/android/android_context_gl.cc +++ b/shell/platform/android/android_context_gl.cc @@ -240,7 +240,7 @@ AndroidEGLSurface::AndroidEGLSurface(EGLSurface surface, } AndroidEGLSurface::~AndroidEGLSurface() { - auto result = eglDestroySurface(display_, surface_); + [[maybe_unused]] auto result = eglDestroySurface(display_, surface_); FML_DCHECK(result == EGL_TRUE); } diff --git a/shell/platform/android/android_image_generator.cc b/shell/platform/android/android_image_generator.cc index 85866423d1551..b614f8ebad5b8 100644 --- a/shell/platform/android/android_image_generator.cc +++ b/shell/platform/android/android_image_generator.cc @@ -96,9 +96,9 @@ void AndroidImageGenerator::DoDecodeImage() { fml::jni::ScopedJavaGlobalRef* bitmap = new fml::jni::ScopedJavaGlobalRef( - env, env->CallStaticObjectMethod(g_flutter_jni_class->obj(), - g_decode_image_method, - direct_buffer.obj(), (long)this)); + env, env->CallStaticObjectMethod( + g_flutter_jni_class->obj(), g_decode_image_method, + direct_buffer.obj(), reinterpret_cast(this))); FML_CHECK(fml::jni::CheckException(env)); if (bitmap->is_null()) { @@ -106,7 +106,7 @@ void AndroidImageGenerator::DoDecodeImage() { } AndroidBitmapInfo info; - int status; + [[maybe_unused]] int status; if ((status = AndroidBitmap_getInfo(env, bitmap->obj(), &info)) < 0) { FML_DLOG(ERROR) << "Failed to get bitmap info, status=" << status; return; diff --git a/shell/platform/android/android_image_generator.h b/shell/platform/android/android_image_generator.h index 4ddd6b95cc7fc..ce62163a88f3c 100644 --- a/shell/platform/android/android_image_generator.h +++ b/shell/platform/android/android_image_generator.h @@ -38,12 +38,11 @@ class AndroidImageGenerator : public ImageGenerator { SkISize GetScaledDimensions(float desired_scale) override; // |ImageGenerator| - bool GetPixels( - const SkImageInfo& info, - void* pixels, - size_t row_bytes, - unsigned int frame_index = 0, - std::optional prior_frame = std::nullopt) override; + bool GetPixels(const SkImageInfo& info, + void* pixels, + size_t row_bytes, + unsigned int frame_index, + std::optional prior_frame) override; void DecodeImage(); diff --git a/shell/platform/android/android_surface_gl.cc b/shell/platform/android/android_surface_gl.cc index 237cf2105d8c4..39599e2e10f8e 100644 --- a/shell/platform/android/android_surface_gl.cc +++ b/shell/platform/android/android_surface_gl.cc @@ -175,7 +175,7 @@ sk_sp AndroidSurfaceGL::GetGLInterface() const { EGLDisplay display = eglGetCurrentDisplay(); EGLSurface draw_surface = eglGetCurrentSurface(EGL_DRAW); EGLSurface read_surface = eglGetCurrentSurface(EGL_READ); - EGLBoolean result = + [[maybe_unused]] EGLBoolean result = eglMakeCurrent(display, draw_surface, read_surface, new_context); FML_DCHECK(result == EGL_TRUE); result = eglMakeCurrent(display, draw_surface, read_surface, old_context); diff --git a/shell/platform/common/json_message_codec.cc b/shell/platform/common/json_message_codec.cc index ae362f736cde6..76229323a7134 100644 --- a/shell/platform/common/json_message_codec.cc +++ b/shell/platform/common/json_message_codec.cc @@ -21,9 +21,11 @@ const JsonMessageCodec& JsonMessageCodec::GetInstance() { std::unique_ptr> JsonMessageCodec::EncodeMessageInternal( const rapidjson::Document& message) const { - // TODO: Look into alternate writers that would avoid the buffer copy. rapidjson::StringBuffer buffer; rapidjson::Writer writer(buffer); + // clang-tidy has trouble reasoning about some of the complicated array and + // pointer-arithmetic code in rapidjson. + // NOLINTNEXTLINE(clang-analyzer-core.*) message.Accept(writer); const char* buffer_start = buffer.GetString(); return std::make_unique>( diff --git a/shell/platform/common/json_message_codec_unittests.cc b/shell/platform/common/json_message_codec_unittests.cc index b31f33fca0f61..e95de83865c91 100644 --- a/shell/platform/common/json_message_codec_unittests.cc +++ b/shell/platform/common/json_message_codec_unittests.cc @@ -27,6 +27,7 @@ static void CheckEncodeDecode(const rapidjson::Document& value) { // Tests that a JSON document with various data types round-trips correctly. TEST(JsonMessageCodec, EncodeDecode) { + // NOLINTNEXTLINE(clang-analyzer-core.NullDereference) rapidjson::Document array(rapidjson::kArrayType); auto& allocator = array.GetAllocator(); diff --git a/shell/platform/common/json_method_codec.cc b/shell/platform/common/json_method_codec.cc index 6d69cca94ceb1..c189c6f86baee 100644 --- a/shell/platform/common/json_method_codec.cc +++ b/shell/platform/common/json_method_codec.cc @@ -101,6 +101,7 @@ JsonMethodCodec::EncodeErrorEnvelopeInternal( const std::string& error_code, const std::string& error_message, const rapidjson::Document* error_details) const { + // NOLINTNEXTLINE(clang-analyzer-core.NullDereference) rapidjson::Document envelope(rapidjson::kArrayType); auto& allocator = envelope.GetAllocator(); envelope.PushBack(rapidjson::Value(error_code, allocator), allocator); diff --git a/shell/platform/common/json_method_codec_unittests.cc b/shell/platform/common/json_method_codec_unittests.cc index 425233af00903..4989192fab56e 100644 --- a/shell/platform/common/json_method_codec_unittests.cc +++ b/shell/platform/common/json_method_codec_unittests.cc @@ -124,6 +124,7 @@ TEST(JsonMethodCodec, HandlesErrorEnvelopesWithNulls) { TEST(JsonMethodCodec, HandlesErrorEnvelopesWithDetails) { const JsonMethodCodec& codec = JsonMethodCodec::GetInstance(); + // NOLINTNEXTLINE(clang-analyzer-core.NullDereference) rapidjson::Document details(rapidjson::kArrayType); auto& allocator = details.GetAllocator(); details.PushBack("a", allocator); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 2779831987eb4..30d1d1d8004c4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -952,6 +952,8 @@ - (void)sendOnChannel:(NSString*)channel channel.UTF8String, flutter::CopyNSDataToMapping(message), response); _shell->GetPlatformView()->DispatchPlatformMessage(std::move(platformMessage)); + // platformMessage takes ownership of response. + // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) } - (NSObject*)makeBackgroundTaskQueue { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm index 1bc6e9b8dbba2..5c27801f3a46f 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm @@ -1653,7 +1653,6 @@ - (UITextPosition*)closestPositionToPoint:(CGPoint)point withinRange:(UITextRang if (position <= end) { if (IsSelectionRectCloserToPoint(point, _selectionRects[i].rect, _closestRect, /*checkRightBoundary=*/YES)) { - _closestIndex = [_selectionRects count]; _closestPosition = position; } } diff --git a/shell/platform/darwin/ios/ios_render_target_gl.mm b/shell/platform/darwin/ios/ios_render_target_gl.mm index 28fb24263b262..5c9fd2a7f939a 100644 --- a/shell/platform/darwin/ios/ios_render_target_gl.mm +++ b/shell/platform/darwin/ios/ios_render_target_gl.mm @@ -22,7 +22,7 @@ [layer_ setPresentsWithTransaction:YES]; } auto context_switch = GLContextSwitch(std::make_unique(context_.get())); - bool context_current = context_switch.GetResult(); + [[maybe_unused]] bool context_current = context_switch.GetResult(); FML_DCHECK(context_current); FML_DCHECK(glGetError() == GL_NO_ERROR); diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponder.mm b/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponder.mm index 1a0747b3b59be..cf3e397a84612 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponder.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponder.mm @@ -166,12 +166,12 @@ static uint64_t GetLogicalKeyForEvent(NSEvent* event, uint64_t physicalKey) { uint32_t* keyLabel = DecodeUtf16(keyLabelUtf16, &keyLabelLength); if (keyLabelLength == 1) { uint32_t keyLabelChar = *keyLabel; - delete[] keyLabel; NSCAssert(!IsControlCharacter(keyLabelChar) && !IsUnprintableKey(keyLabelChar), @"Unexpected control or unprintable keylabel 0x%x", keyLabelChar); NSCAssert(keyLabelChar <= 0x10FFFF, @"Out of range keylabel 0x%x", keyLabelChar); character = keyLabelChar; } + delete[] keyLabel; } if (character != 0) { return KeyOfPlane(toLower(character), kUnicodePlane); diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponderUnittests.mm b/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponderUnittests.mm index f61f1c99308b2..359bdc37e8012 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponderUnittests.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEmbedderKeyResponderUnittests.mm @@ -31,7 +31,7 @@ - (instancetype)initWithEvent:(const FlutterKeyEvent*)event if (event->character != nullptr) { size_t len = strlen(event->character); char* character = new char[len + 1]; - strcpy(character, event->character); + strlcpy(character, event->character, sizeof(character)); _data->character = character; } _callback = callback; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index 0b341865f7903..4341f89fb1dce 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -18,6 +18,9 @@ #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h" #include "flutter/testing/test_dart_native_resolver.h" +// CREATE_NATIVE_ENTRY and MOCK_ENGINE_PROC are leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + @interface FlutterEngine (Test) /** * The FlutterCompositor object currently in use by the FlutterEngine. This is @@ -343,7 +346,7 @@ @interface FlutterEngine (Test) ASSERT_TRUE(latch_called); } -// TODO: Enable after https://github.com/flutter/flutter/issues/96668 is fixed. +// TODO(iskakaushik): Enable after https://github.com/flutter/flutter/issues/96668 is fixed. TEST(FlutterEngine, DISABLED_Compositor) { NSString* fixtures = @(flutter::testing::GetFixturesPath()); FlutterDartProject* project = [[FlutterDartProject alloc] @@ -475,3 +478,5 @@ @interface FlutterEngine (Test) } } // namespace flutter::testing + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRendererTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRendererTest.mm index a1d9a5d76cecf..df53d94dcae70 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRendererTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterOpenGLRendererTest.mm @@ -13,6 +13,9 @@ #include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h" #include "flutter/testing/testing.h" +// MOCK_ENGINE_PROC is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + @interface TestOpenGLEngine : FlutterEngine @property(nonatomic, readwrite) id renderer; @@ -134,3 +137,5 @@ - (nullable instancetype)initWithGLRenderer { } } // namespace flutter::testing + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMacTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMacTest.mm index c3ac3fcba397e..b2932ff6f69b4 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMacTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterPlatformNodeDelegateMacTest.mm @@ -137,6 +137,9 @@ EXPECT_EQ(selection.length, 0u); } +// MOCK_ENGINE_PROC is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + TEST(FlutterPlatformNodeDelegateMac, CanPerformAction) { FlutterEngine* engine = CreateTestEngine(); @@ -211,6 +214,8 @@ [engine shutDownEngine]; } +// NOLINTEND(clang-analyzer-core.StackAddressEscape) + TEST(FlutterPlatformNodeDelegateMac, TextFieldUsesFlutterTextField) { FlutterEngine* engine = CreateTestEngine(); NSString* fixtures = @(testing::GetFixturesPath()); @@ -220,6 +225,9 @@ FlutterViewController* viewController = [[FlutterViewController alloc] initWithProject:project]; [viewController loadView]; [engine setViewController:viewController]; + + // Unit test localization is unnecessary. + // NOLINTNEXTLINE(clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker) viewController.textInputPlugin.string = @"textfield"; // Creates a NSWindow so that the native text field can become first responder. NSWindow* window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 800, 600) @@ -291,4 +299,4 @@ EXPECT_EQ([native_text_field.stringValue isEqualToString:@"textfield"], YES); } -} // flutter::testing +} // namespace flutter::testing diff --git a/shell/platform/embedder/tests/embedder_a11y_unittests.cc b/shell/platform/embedder/tests/embedder_a11y_unittests.cc index 9f06542b9d578..4f15ad68afe4d 100644 --- a/shell/platform/embedder/tests/embedder_a11y_unittests.cc +++ b/shell/platform/embedder/tests/embedder_a11y_unittests.cc @@ -16,6 +16,9 @@ #include "flutter/shell/platform/embedder/tests/embedder_config_builder.h" #include "flutter/testing/testing.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -204,3 +207,5 @@ TEST_F(Embedder11yTest, A11yTreeIsConsistent) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/platform/embedder/tests/embedder_unittests.cc b/shell/platform/embedder/tests/embedder_unittests.cc index 5dccfab382910..850e453c63f75 100644 --- a/shell/platform/embedder/tests/embedder_unittests.cc +++ b/shell/platform/embedder/tests/embedder_unittests.cc @@ -31,6 +31,9 @@ #include "third_party/skia/include/core/SkSurface.h" #include "third_party/tonic/converter/dart_converter.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace { static uint64_t NanosFromEpoch(int millis_from_now) { @@ -1743,3 +1746,5 @@ TEST_F(EmbedderTest, VsyncCallbackPostedIntoFuture) { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/platform/embedder/tests/embedder_unittests_gl.cc b/shell/platform/embedder/tests/embedder_unittests_gl.cc index 94f2eddb42fde..4b62750fe1084 100644 --- a/shell/platform/embedder/tests/embedder_unittests_gl.cc +++ b/shell/platform/embedder/tests/embedder_unittests_gl.cc @@ -36,6 +36,9 @@ #include "third_party/skia/src/gpu/gl/GrGLDefines.h" #include "third_party/tonic/converter/dart_converter.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -3696,3 +3699,5 @@ INSTANTIATE_TEST_SUITE_P( } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/platform/embedder/tests/embedder_unittests_metal.mm b/shell/platform/embedder/tests/embedder_unittests_metal.mm index 32432fb8a4ce8..8e2bbf948bbdb 100644 --- a/shell/platform/embedder/tests/embedder_unittests_metal.mm +++ b/shell/platform/embedder/tests/embedder_unittests_metal.mm @@ -19,6 +19,9 @@ #include "flutter/testing/assertions_skia.h" #include "flutter/testing/testing.h" +// CREATE_NATIVE_ENTRY is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + namespace flutter { namespace testing { @@ -483,3 +486,5 @@ void Collect() { } // namespace testing } // namespace flutter + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/shell/platform/glfw/key_event_handler.cc b/shell/platform/glfw/key_event_handler.cc index 94244bd9b1682..5654ce8e9a999 100644 --- a/shell/platform/glfw/key_event_handler.cc +++ b/shell/platform/glfw/key_event_handler.cc @@ -119,6 +119,7 @@ void KeyEventHandler::KeyboardHook(GLFWwindow* window, int mods) { // TODO: Translate to a cross-platform key code system rather than passing // the native key code. + // NOLINTNEXTLINE(clang-analyzer-core.NullDereference) rapidjson::Document event(rapidjson::kObjectType); auto& allocator = event.GetAllocator(); event.AddMember(kKeyCodeKey, key, allocator); diff --git a/shell/platform/linux/fl_basic_message_channel_test.cc b/shell/platform/linux/fl_basic_message_channel_test.cc index 67f85d64e4de6..8811fa388af83 100644 --- a/shell/platform/linux/fl_basic_message_channel_test.cc +++ b/shell/platform/linux/fl_basic_message_channel_test.cc @@ -17,6 +17,8 @@ #include "flutter/shell/platform/linux/testing/mock_renderer.h" // Checks sending a message without a response works. +// MOCK_ENGINE_PROC is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) TEST(FlBasicMessageChannelTest, SendMessageWithoutResponse) { g_autoptr(GMainLoop) loop = g_main_loop_new(nullptr, 0); @@ -58,6 +60,7 @@ TEST(FlBasicMessageChannelTest, SendMessageWithoutResponse) { EXPECT_TRUE(called); } +// NOLINTEND(clang-analyzer-core.StackAddressEscape) // Called when the message response is received in the SendMessage test. static void echo_response_cb(GObject* object, diff --git a/shell/platform/linux/fl_engine_test.cc b/shell/platform/linux/fl_engine_test.cc index d2f6d408ab34c..6121adf0d0633 100644 --- a/shell/platform/linux/fl_engine_test.cc +++ b/shell/platform/linux/fl_engine_test.cc @@ -11,6 +11,9 @@ #include "flutter/shell/platform/linux/public/flutter_linux/fl_json_message_codec.h" #include "flutter/shell/platform/linux/testing/fl_test.h" +// MOCK_ENGINE_PROC is leaky by design +// NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) + // Checks sending window metrics events works. TEST(FlEngineTest, WindowMetrics) { g_autoptr(FlEngine) engine = make_mock_engine(); @@ -315,3 +318,5 @@ TEST(FlEngineTest, DartEntrypointArgs) { EXPECT_TRUE(called); } + +// NOLINTEND(clang-analyzer-core.StackAddressEscape) diff --git a/testing/mock_canvas.cc b/testing/mock_canvas.cc index 9084563973dc6..0132af7fe1a40 100644 --- a/testing/mock_canvas.cc +++ b/testing/mock_canvas.cc @@ -79,14 +79,12 @@ void MockCanvas::onDrawTextBlob(const SkTextBlob* text, // This duplicates existing logic in SkCanvas::onDrawPicture // that should probably be split out so it doesn't need to be here as well. SkRect storage; - const SkRect* bounds = nullptr; if (paint.canComputeFastBounds()) { storage = text->bounds().makeOffset(x, y); SkRect tmp; if (this->quickReject(paint.computeFastBounds(storage, &tmp))) { return; } - bounds = &storage; } draw_calls_.emplace_back(DrawCall{