summaryrefslogtreecommitdiffstats
path: root/build/clang-plugin/tests/TestDanglingOnTemporary.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /build/clang-plugin/tests/TestDanglingOnTemporary.cpp
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'build/clang-plugin/tests/TestDanglingOnTemporary.cpp')
-rw-r--r--build/clang-plugin/tests/TestDanglingOnTemporary.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/build/clang-plugin/tests/TestDanglingOnTemporary.cpp b/build/clang-plugin/tests/TestDanglingOnTemporary.cpp
new file mode 100644
index 0000000000..62a7755ece
--- /dev/null
+++ b/build/clang-plugin/tests/TestDanglingOnTemporary.cpp
@@ -0,0 +1,45 @@
+#define MOZ_NO_DANGLING_ON_TEMPORARIES \
+ __attribute__((annotate("moz_no_dangling_on_temporaries")))
+
+class AnnotateConflict {
+ MOZ_NO_DANGLING_ON_TEMPORARIES int *get() && { return nullptr; } // expected-error {{methods annotated with MOZ_NO_DANGLING_ON_TEMPORARIES cannot be && ref-qualified}}
+ MOZ_NO_DANGLING_ON_TEMPORARIES int test() { return 0; } // expected-error {{methods annotated with MOZ_NO_DANGLING_ON_TEMPORARIES must return a pointer}}
+};
+
+class NS_ConvertUTF8toUTF16 {
+public:
+ MOZ_NO_DANGLING_ON_TEMPORARIES int *get() { return nullptr; }
+ operator int*()
+ {
+ return get(); // This should be ignored because the call is implcitly on this
+ }
+};
+
+NS_ConvertUTF8toUTF16 TemporaryFunction() { return NS_ConvertUTF8toUTF16(); }
+
+void UndefinedFunction(int* test);
+
+void NoEscapeFunction(int *test) {}
+
+int *glob; // expected-note {{through the variable declared here}}
+void EscapeFunction1(int *test) { glob = test; } // expected-note {{the raw pointer escapes the function scope here}}
+
+void EscapeFunction2(int *test, int *&escape) { escape = test; } // expected-note {{the raw pointer escapes the function scope here}} \
+ expected-note {{through the parameter declared here}}
+
+int *EscapeFunction3(int *test) { return test; } // expected-note {{the raw pointer escapes the function scope here}} \
+ expected-note {{through the return value of the function declared here}}
+
+int main() {
+ int *test = TemporaryFunction().get(); // expected-error {{calling `get` on a temporary, potentially allowing use after free of the raw pointer}}
+ int *test2 = NS_ConvertUTF8toUTF16().get(); // expected-error {{calling `get` on a temporary, potentially allowing use after free of the raw pointer}}
+
+ UndefinedFunction(NS_ConvertUTF8toUTF16().get());
+
+ NoEscapeFunction(TemporaryFunction().get());
+ EscapeFunction1(TemporaryFunction().get()); // expected-error {{calling `get` on a temporary, potentially allowing use after free of the raw pointer}}
+
+ int *escape;
+ EscapeFunction2(TemporaryFunction().get(), escape); // expected-error {{calling `get` on a temporary, potentially allowing use after free of the raw pointer}}
+ int *escape2 = EscapeFunction3(TemporaryFunction().get()); // expected-error {{calling `get` on a temporary, potentially allowing use after free of the raw pointer}}
+}