clang_wrap.h: do not return reference to local object in getFile
authorSven Verdoolaege <sven.verdoolaege@gmail.com>
Thu, 23 Oct 2025 13:53:49 +0000 (23 15:53 +0200)
committerSven Verdoolaege <sven.verdoolaege@gmail.com>
Sat, 22 Nov 2025 14:26:18 +0000 (22 15:26 +0100)
The getFileRef method returns an llvm::Expected<clang::FileEntryRef>, and
operator* on an llvm::Expected returns a reference to the embedded object,
which is destroyed when getFile returns.  This problem is usually masked by
compiler optimizations.

Return the llvm::Expected<clang::FileEntryRef> object itself.

Note that the caller does not need to be adjusted because
an llvm::ErrorOr<clang::FileEntryRef> behaves similarly
to an llvm::Expected in the sense that they both evaluate
to false in the case of an error and they can both
be dereferenced to obtain the embedded object.

Reported-by: Leo Yin <yinle2025@gmail.com>
Signed-off-by: Sven Verdoolaege <sven.verdoolaege@gmail.com>
interface/include/isl-interface/clang_wrap.h

index 61b984e..8cb025f 100644 (file)
@@ -268,22 +268,21 @@ public:
     static constexpr bool value = type::value;
 };
 
-/* Return the FileEntryRef/FileEntry corresponding to the given file name or
- * an error if anything went wrong.
+/* Return a wrapper around the FileEntryRef/FileEntry
+ * corresponding to the given file name.  The wrapper evaluates
+ * to false if an error occurs.
  *
  * If T (= FileManager) has a getFileRef method, then call that and
- * return a FileEntryRef.
- * Otherwise, call getFile and return a FileEntry (pointer).
+ * return an llvm::Expected<clang::FileEntryRef>.
+ * Otherwise, call getFile and return a FileEntry (pointer) embedded
+ * in an llvm::ErrorOr.
  */
 template <typename T,
        typename std::enable_if<HasGetFileRef<T>::value, bool>::type = true>
 static auto getFile(T& obj, const std::string &filename)
-       -> llvm::ErrorOr<decltype(*obj.getFileRef(filename))>
+       -> decltype(obj.getFileRef(filename))
 {
-       auto file = obj.getFileRef(filename);
-       if (!file)
-           return std::error_code();
-       return *file;
+       return obj.getFileRef(filename);
 }
 template <typename T,
        typename std::enable_if<!HasGetFileRef<T>::value, bool>::type = true>